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()}` /** * 원본 이미지를 우선 저장한다. * 이미지 이름이 겹지는 현상을 방지하기 위해 uuid 를 사용한다. */ await s3.send( new PutObjectCommand({ Bucket, Key: OriginalKey, Body: Buffer.from(await file.arrayBuffer()), ContentType: 'image/png', }), ) /** * 저장된 원본 이미지를 기준으로 크롭여부를 결정하여 크롭 이미지를 저장한다. */ const bufferImage = await cropImage(OriginalKey, width, height, left, top) /** * 크롭 이미지 이름을 결정한다. */ const Key = `Drawing/${objectNo}_${planNo}_${type}` /** * 크롭이 완료된 이미지를 업로드한다. */ 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 }) } }