From af29c83eb421dc5696b3f47007331e496649a445 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Thu, 19 Jun 2025 13:04:02 +0900 Subject: [PATCH] =?UTF-8?q?[1115]=20:=20[=E8=A6=8B=E7=A9=8D=E6=9B=B8?= =?UTF-8?q?=E4=BD=9C=E6=88=90=E5=BE=8C=E3=81=AE=E5=9B=B3=E9=9D=A2=E3=81=AE?= =?UTF-8?q?=E5=A4=A7=E3=81=8D=E3=81=95=E3=82=92=E8=AA=BF=E6=95=B4=E3=81=97?= =?UTF-8?q?=E3=81=A6=E6=AC=B2=E3=81=97=E3=81=84]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [작업내용] : 엑셀 다운로드 pdf 다운로드 이미지 비율 수정 --- src/app/api/image/canvas/route.js | 64 +++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/src/app/api/image/canvas/route.js b/src/app/api/image/canvas/route.js index 2a20da92..600951fb 100644 --- a/src/app/api/image/canvas/route.js +++ b/src/app/api/image/canvas/route.js @@ -38,10 +38,14 @@ const cropImage = async (Key, width, height, left, top) => { } const buffer = Buffer.concat(chunks) - const image = await Jimp.read(buffer) - + let image = await Jimp.read(buffer) image.autocrop({ tolerance: 0.0002, leaveBorder: 10 }) - return await image.getBuffer('image/png') + + const resizedImage = await resizeImage(image).then((result) => { + return result + }) + + return await resizedImage.getBuffer('image/png') // Convert stream to buffer // const chunks = [] @@ -77,6 +81,60 @@ const cropImage = async (Key, width, height, left, top) => { } } +//크롭된 이미지를 가지고 높이 기준 -> 너비 기준으로 비율 변경 후 이미지에 추가 +const resizeImage = async (image) => { + // //이미지를 cm로 변환 + let imageHeightCm = Math.round((image.bitmap.height * 2.54) / 96) //원본 이미지 센치로 변환 + let imageWidthCm = Math.round((image.bitmap.width * 2.54) / 96) //원본 이미지 센치로 변환 + const calcWidthRatio = 12.89 / imageHeightCm //원본 비율 계산 + + let convertHeightCm = Math.round(imageHeightCm * calcWidthRatio) //변환된 이미지 CM + let convertWidthCm = Math.round(imageWidthCm * calcWidthRatio) //변환된 이미지 CM + + let convertHeightBitmap = Math.round((convertHeightCm * 96) / 2.54) //비트맵 사이즈로 변환 + let convertWidthBitmap = Math.round((convertWidthCm * 96) / 2.54) //비트맵 사이즈로 변환 + + //높이 기준으로 리사이즈를 함 + image.resize({ w: convertWidthBitmap, h: convertHeightBitmap, mode: Jimp.RESIZE_BILINEAR }) + + //높이를 기준으로 변경 후에 가로 폭이 더 넓으면 가로폭 기준으로 다시 사이즈를 조절한다 + if (convertWidthCm > 35.4) { + //너비가 더 클때 + imageHeightCm = Math.round((image.bitmap.height * 2.54) / 96) //높이 기준으로 리사이즈된 이미지 크기 + imageWidthCm = Math.round((image.bitmap.width * 2.54) / 96) //높이 기준으로 리사이즈된 이미지 크기 + + const calcWidthRatio = 35.4 / imageWidthCm //리사이즈된 이미지 가로 비율 계산 + + convertHeightCm = Math.round(imageHeightCm * calcWidthRatio) //너비 기준 이미지 비율 계산 + convertWidthCm = Math.round(imageWidthCm * calcWidthRatio) //변환된 이미지 CM + + convertHeightBitmap = Math.round((convertHeightCm * 96) / 2.54) //비트맵 사이즈로 변환 + convertWidthBitmap = Math.round((convertWidthCm * 96) / 2.54) //비트맵 사이즈로 변환 + + image.resize({ w: convertWidthBitmap, h: convertHeightBitmap, mode: Jimp.RESIZE_BILINEAR }) //이미지 리사이즈 + } + + //엑셀 템플릿 너비 35.4cm, 높이 12.89cm + const convertStandardWidth = Math.round((35.4 * 96) / 2.54) + const convertStandardHeight = Math.round((12.89 * 96) / 2.54) + + //엑셀 템플릿 사이즈로 배경 이미지를 생성 + const mixedImage = new Jimp({ width: convertStandardWidth, height: convertStandardHeight, color: 0xffffffff }) + + //이미지를 중앙에 배치 + const x = Math.floor((mixedImage.bitmap.width - image.bitmap.width) / 2) + const y = Math.floor((mixedImage.bitmap.height - image.bitmap.height) / 2) + + //이미지를 배경 이미지에 합성 + mixedImage.composite(image, x, y, { + mode: Jimp.BLEND_SOURCE_OVER, + opacitySource: 1, // 원본 투명도 유지 + opacityDest: 1, + }) + + return mixedImage +} + export async function POST(req) { try { const formData = await req.formData()