Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 23 additions & 9 deletions scripts/sharp-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@ export const SHARP_OPTIONS: {
avif: {
quality: 65,
},
gif: {
effort: 7,
dither: 0.5,
},
gif: {},
}
export type SharpOptionType = keyof typeof SHARP_OPTIONS

Expand All @@ -31,7 +28,7 @@ export const SHARP_OPTIONS_TYPE_MAPPER = {
jpeg: 'jpeg',
webp: 'webp',
avif: 'avif',
gif: 'gif',
gif: 'webp',
} as const satisfies { [key: string]: SharpOptionType }
export type SharpFileType = keyof typeof SHARP_OPTIONS_TYPE_MAPPER

Expand Down Expand Up @@ -96,7 +93,15 @@ export const sharpImages = async () => {
const sharpOptionType = SHARP_OPTIONS_TYPE_MAPPER[fileType]
const sharpOption = SHARP_OPTIONS[sharpOptionType]

const sharpedFilePath = filePath.replace(`.${fileType}`, `.sharp.${fileType}`)
const metadata = await sharp(filePath).metadata()
const isAnimatedWebp = fileType === 'webp' && metadata.pages && metadata.pages > 1

if (isAnimatedWebp) {
console.log(`::✧:: Skipping animated WebP file ${filename}`)
continue
}

const sharpedFilePath = filePath.replace(`.${fileType}`, `.sharp.${sharpOptionType}`)

await sharp(filePath, fileType === 'gif' ? { animated: true } : {})
[sharpOptionType](sharpOption)
Expand All @@ -114,9 +119,8 @@ export const sharpImages = async () => {
}

if (processedResult.percentChange > 0) {
await fs.writeFile(filePath, await fs.readFile(sharpedFilePath))

if (fileType !== 'gif') {
await fs.writeFile(filePath, await fs.readFile(sharpedFilePath))
const avifPath = filePath.replace(`.${fileType}`, '.avif')
await sharp(filePath).avif(SHARP_OPTIONS.avif).toFile(avifPath)
const avifStats = await fs.stat(avifPath)
Expand All @@ -134,12 +138,22 @@ export const sharpImages = async () => {
}
}

if (fileType === 'gif') {
const webpPath = filePath.replace('.gif', '.webp')
await fs.rename(sharpedFilePath, webpPath)
const webpFilename = path.basename(webpPath)
mdxUpdates += await updateMdxReferences(filename, webpFilename)
await unlink(filePath)
}

sharpedImageList.push(processedResult)
} else {
unSharpedImageList.push(processedResult)
}

await unlink(sharpedFilePath)
if (fileType !== 'gif') {
await unlink(sharpedFilePath)
}
} catch (error) {
console.log('::error::', error)
}
Expand Down
4 changes: 2 additions & 2 deletions src/content/post/blog/cubeit-intranet-retrospect.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ SQLite3는 선택사항이었지만, 김민태 강사님께서 SQL 문을 사용
디자인이 나와야 개발을 시작할 수 있어서 레퍼런스를 활용해 주말에 빠르게 작업했다.
조장님(진짜 디자이너)이 레퍼런스도 구해주시고 피드백도 빠르게 주셔서 좀 더 수월하게 작업할 수 있었다.

![반응형으로 구현한 모습](/images/cubeit-intranet-retrospect/mediaquery.gif)
![반응형으로 구현한 모습](/images/cubeit-intranet-retrospect/mediaquery.webp)

## 역할

Expand Down Expand Up @@ -139,7 +139,7 @@ Cube.IT 인트라넷 서비스는 크게 **로그인, 홈, 프로필, 구성원,
이미지 파일을 업로드하면 **Cloudinary**를 이용해 **url로 변환**한 다음, **데이터베이스에 저장**한다.
그대로 데이터베이스에 저장할 수도 있었지만, 용량 최적화를 위해 Cloudinary 서비스를 이용했다.

![랜덤 프로필 이미지 생성](/images/cubeit-intranet-retrospect/random-profile-image.gif)
![랜덤 프로필 이미지 생성](/images/cubeit-intranet-retrospect/random-profile-image.webp)

`기본 이미지 설정`을 클릭하면 [DiceBear](https://www.dicebear.com/) API의 Lorelei 스타일 **아바타를 랜덤으로 설정**해주는 이스터에그 같은 기능을 추가했다.
처음 만들었을 때 재미있어서 홀린 듯이 계속 눌러봤던 기억이 있다. 🤣
Expand Down