134 lines
3.4 KiB
JavaScript
134 lines
3.4 KiB
JavaScript
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}.png`
|
|
|
|
/**
|
|
* 크롭이 완료된 이미지를 업로드한다.
|
|
*/
|
|
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 })
|
|
}
|
|
}
|