feat: 캔버스 이미지 S3로 저장 기능 추가
This commit is contained in:
parent
11edbe1988
commit
97389f7141
120
src/app/api/image/canvas/route.js
Normal file
120
src/app/api/image/canvas/route.js
Normal 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 })
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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,
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user