본문 이미지 최적화 및 백필 보정
This commit is contained in:
@@ -3,17 +3,19 @@ import { mkdir, stat } from 'node:fs/promises'
|
||||
import { dirname, extname, join, posix } from 'node:path'
|
||||
import sharp from 'sharp'
|
||||
import {
|
||||
getPostBodyPreviewThumbnailUrl,
|
||||
getPostBodyThumbnailUrl,
|
||||
isPostBodyThumbnailUrl,
|
||||
isPostCardThumbnailUrl
|
||||
} from '../../lib/post-card-thumbnail-url.js'
|
||||
|
||||
export { getPostBodyThumbnailUrl, isPostBodyThumbnailUrl, isPostCardThumbnailUrl }
|
||||
export { getPostBodyPreviewThumbnailUrl, getPostBodyThumbnailUrl, isPostBodyThumbnailUrl, isPostCardThumbnailUrl }
|
||||
|
||||
export const POST_THUMBNAIL_WIDTH = 640
|
||||
export const POST_THUMBNAIL_HEIGHT = 360
|
||||
export const POST_THUMBNAIL_QUALITY = 82
|
||||
export const POST_BODY_IMAGE_WIDTH = 1600
|
||||
export const POST_BODY_PREVIEW_IMAGE_WIDTH = 720
|
||||
export const POST_BODY_IMAGE_QUALITY = 84
|
||||
|
||||
const postUploadUrlPattern = /^\/uploads\/posts\/\d{4}\/\d{2}\/[^/?#]+$/i
|
||||
@@ -114,6 +116,21 @@ export const getPostBodyThumbnailDiskPath = (imageUrl) => {
|
||||
return join(process.cwd(), 'public', decodeUrlPathPart(thumbnailUrl.replace(/^\/+/, '')))
|
||||
}
|
||||
|
||||
/**
|
||||
* 게시물 작은 본문 표시용 이미지 URL의 디스크 경로를 조회한다.
|
||||
* @param {string|null|undefined} imageUrl - 원본 이미지 URL
|
||||
* @returns {string} 작은 본문 표시용 이미지 디스크 경로
|
||||
*/
|
||||
export const getPostBodyPreviewThumbnailDiskPath = (imageUrl) => {
|
||||
const thumbnailUrl = getPostBodyPreviewThumbnailUrl(imageUrl)
|
||||
|
||||
if (!thumbnailUrl) {
|
||||
return ''
|
||||
}
|
||||
|
||||
return join(process.cwd(), 'public', decodeUrlPathPart(thumbnailUrl.replace(/^\/+/, '')))
|
||||
}
|
||||
|
||||
/**
|
||||
* 게시물 원본 이미지 URL의 디스크 경로를 조회한다.
|
||||
* @param {string|null|undefined} imageUrl - 원본 이미지 URL
|
||||
@@ -175,6 +192,21 @@ export const getExistingPostBodyThumbnailUrl = (imageUrl) => {
|
||||
return existsSync(getPostBodyThumbnailDiskPath(imageUrl)) ? thumbnailUrl : ''
|
||||
}
|
||||
|
||||
/**
|
||||
* 이미 생성된 작은 게시물 본문 표시용 이미지 URL을 조회한다.
|
||||
* @param {string|null|undefined} imageUrl - 원본 이미지 URL
|
||||
* @returns {string} 존재하는 작은 본문 표시용 이미지 URL
|
||||
*/
|
||||
export const getExistingPostBodyPreviewThumbnailUrl = (imageUrl) => {
|
||||
const thumbnailUrl = getPostBodyPreviewThumbnailUrl(imageUrl)
|
||||
|
||||
if (!thumbnailUrl) {
|
||||
return ''
|
||||
}
|
||||
|
||||
return existsSync(getPostBodyPreviewThumbnailDiskPath(imageUrl)) ? thumbnailUrl : ''
|
||||
}
|
||||
|
||||
/**
|
||||
* 게시물 대표 이미지의 카드 썸네일을 생성하거나 다시 생성한다.
|
||||
* @param {string|null|undefined} imageUrl - 원본 이미지 URL
|
||||
@@ -221,8 +253,9 @@ export const createPostBodyThumbnailForImageUrl = async (imageUrl) => {
|
||||
const sourcePath = getPostImageDiskPath(imageUrl)
|
||||
const thumbnailUrl = getPostBodyThumbnailUrl(imageUrl)
|
||||
const thumbnailPath = getPostBodyThumbnailDiskPath(imageUrl)
|
||||
const previewThumbnailPath = getPostBodyPreviewThumbnailDiskPath(imageUrl)
|
||||
|
||||
if (!sourcePath || !thumbnailUrl || !thumbnailPath) {
|
||||
if (!sourcePath || !thumbnailUrl || !thumbnailPath || !previewThumbnailPath) {
|
||||
return ''
|
||||
}
|
||||
|
||||
@@ -244,6 +277,16 @@ export const createPostBodyThumbnailForImageUrl = async (imageUrl) => {
|
||||
})
|
||||
.webp({ quality: POST_BODY_IMAGE_QUALITY })
|
||||
.toFile(thumbnailPath)
|
||||
|
||||
await sharp(sourcePath)
|
||||
.rotate()
|
||||
.resize({
|
||||
width: POST_BODY_PREVIEW_IMAGE_WIDTH,
|
||||
fit: 'inside',
|
||||
withoutEnlargement: true
|
||||
})
|
||||
.webp({ quality: POST_BODY_IMAGE_QUALITY })
|
||||
.toFile(previewThumbnailPath)
|
||||
} catch {
|
||||
return ''
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user