feat: 캔버스 이미지 S3로 저장 기능 추가

This commit is contained in:
yoosangwook 2025-03-25 11:01:40 +09:00
parent 11edbe1988
commit 97389f7141
3 changed files with 127 additions and 4 deletions

View File

@ -0,0 +1,120 @@
import { NextResponse } from 'next/server'
import { S3Client, PutObjectCommand, DeleteObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3'
import sharp from 'sharp'
import { v4 as uuidv4 } from 'uuid'
const Bucket = process.env.AMPLIFY_BUCKET
const s3 = new S3Client({
region: process.env.AWS_REGION,
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
},
})
const checkArea = (obj) => {
const { width, height, left, top } = obj
if (left < 0 || top < 0 || width > 1600 || height > 1000) {
return false
}
return true
}
const cropImage = async (Key, width, height, left, top) => {
try {
const checkResult = checkArea({ width, height, left, top })
// Get the image from S3
const { Body } = await s3.send(
new GetObjectCommand({
Bucket,
Key,
}),
)
// Convert stream to buffer
const chunks = []
for await (const chunk of Body) {
chunks.push(chunk)
}
const imageBuffer = Buffer.concat(chunks)
let processedImage
if (!checkResult) {
processedImage = await sharp(imageBuffer).toBuffer()
} else {
processedImage = await sharp(imageBuffer)
.extract({
width: parseInt(width),
height: parseInt(height),
left: parseInt(left),
top: parseInt(top),
})
.png()
.toBuffer()
}
return processedImage
} catch (error) {
console.error('Error processing image:', error)
throw error
}
}
export async function POST(req) {
try {
const formData = await req.formData()
const file = formData.get('file')
const objectNo = formData.get('objectNo')
const planNo = formData.get('planNo')
const type = formData.get('type')
const width = formData.get('width')
const height = formData.get('height')
const left = formData.get('left')
const top = formData.get('top')
const OriginalKey = `Drawing/${uuidv4()}`
// Upload original image
await s3.send(
new PutObjectCommand({
Bucket,
Key: OriginalKey,
Body: Buffer.from(await file.arrayBuffer()),
ContentType: 'image/png',
}),
)
// Process the image
const bufferImage = await cropImage(OriginalKey, width, height, left, top)
const Key = `Drawing/${objectNo}_${planNo}_${type}`
// Upload processed image
await s3.send(
new PutObjectCommand({
Bucket,
Key,
Body: bufferImage,
ContentType: 'image/png',
}),
)
await s3.send(
new DeleteObjectCommand({
Bucket,
Key: OriginalKey,
}),
)
const result = {
filePath: `https://${process.env.AMPLIFY_BUCKET}.s3.${process.env.AWS_REGION}.amazonaws.com/${Key}`,
fileName: Key,
}
return NextResponse.json(result)
} catch (error) {
console.error('Error in POST:', error)
return NextResponse.json({ error: 'Failed to process and upload image' }, { status: 500 })
}
}

View File

@ -48,13 +48,15 @@ export async function POST(req) {
export async function DELETE(req) { export async function DELETE(req) {
try { try {
const searchParams = req.nextUrl.searchParams const searchParams = req.nextUrl.searchParams
const Key = `upload/${searchParams.get('fileName')}` const fileName = searchParams.get('fileName')
console.log('🚀 ~ DELETE ~ Key:', Key)
if (!Key) { if (!fileName) {
return NextResponse.json({ error: 'fileName parameter is required' }, { status: 400 }) return NextResponse.json({ error: 'fileName parameter is required' }, { status: 400 })
} }
const Key = `upload/${fileName}`
console.log('🚀 ~ DELETE ~ Key:', Key)
await s3.send( await s3.send(
new DeleteObjectCommand({ new DeleteObjectCommand({
Bucket, Bucket,

View File

@ -79,7 +79,8 @@ export function useImgLoader() {
/** 이미지 크롭 요청 */ /** 이미지 크롭 요청 */
const result = await post({ const result = await post({
url: `${process.env.NEXT_PUBLIC_HOST_URL}/image/canvas`, // url: `${process.env.NEXT_PUBLIC_HOST_URL}/image/canvas`,
url: `http://localhost:3000/api/image/canvas`,
data: formData, data: formData,
}) })
console.log('🚀 ~ handleCanvasToPng ~ result:', result) console.log('🚀 ~ handleCanvasToPng ~ result:', result)