diff --git a/src/main/java/ongjong/namanmoo/service/AwsS3Service.java b/src/main/java/ongjong/namanmoo/service/AwsS3Service.java index c03f7f4..42bedd7 100644 --- a/src/main/java/ongjong/namanmoo/service/AwsS3Service.java +++ b/src/main/java/ongjong/namanmoo/service/AwsS3Service.java @@ -1,5 +1,6 @@ package ongjong.namanmoo.service; +import java.awt.image.BufferedImage; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -17,10 +18,13 @@ import com.amazonaws.services.s3.AmazonS3ClientBuilder; import com.amazonaws.services.s3.model.*; import lombok.extern.slf4j.Slf4j; +import net.coobird.thumbnailator.Thumbnails; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; +import javax.imageio.ImageIO; + @Slf4j @Service public class AwsS3Service { @@ -28,7 +32,6 @@ public class AwsS3Service { private final AmazonS3 amazonS3Client; private final String bucket; private final String region; - /** * AwsS3Service 생성자. * @@ -69,6 +72,12 @@ public String uploadFile(MultipartFile multipartFile) throws IOException { File uploadFile = convertFile(multipartFile) .orElseThrow(() -> new IllegalArgumentException("MultipartFile -> File convert fail")); + // 이미지 파일의 경우 최적화 + if (determineFileType(multipartFile).equals("image")) { + log.info("Optimizing image file..."); + uploadFile = optimizeImageFile(uploadFile); + } + String fileType = determineFileType(multipartFile); String fileName = generateFileName(uploadFile, fileType); @@ -80,6 +89,56 @@ public String uploadFile(MultipartFile multipartFile) throws IOException { return uploadFileUrl; } + /** + * 이미지를 최적화하는 메소드. + * + * @param originalFile 최적화할 원본 이미지 파일 + * @return 최적화된 이미지 파일 + * @throws IOException 이미지 최적화 중 발생하는 예외 + */ + private File optimizeImageFile(File originalFile) throws IOException { + BufferedImage originalImage = ImageIO.read(originalFile); + File optimizedFile = new File("optimized_" + originalFile.getName()); + + // 원본 이미지의 크기 + int originalWidth = originalImage.getWidth(); + int originalHeight = originalImage.getHeight(); + + // 원하는 최대 크기 + int maxWidth = (int) (originalWidth * 0.85); + int maxHeight = (int) (originalHeight * 0.85); + + // 비율 유지하면서 리사이징할 크기 계산 + double aspectRatio = (double) originalWidth / originalHeight; + int newWidth = maxWidth; + int newHeight = (int) (maxWidth / aspectRatio); + if (newHeight > maxHeight) { + newHeight = maxHeight; + newWidth = (int) (maxHeight * aspectRatio); + } + + // 이미지 리사이즈 및 압축 + Thumbnails.of(originalImage) + .size(newWidth, newHeight) // 비율을 유지하면서 리사이즈 + .outputQuality(0.5) // 이미지 품질 설정 (0.0 ~ 1.0) + .toFile(optimizedFile); + + + // 원본 이미지 파일의 크기 + long originalFileSize = originalFile.length(); + // 최적화된 이미지 파일의 크기 + long optimizedFileSize = optimizedFile.length(); + + // 로그 출력 + log.info("Original Image Dimensions: {}x{}", originalWidth, originalHeight); + log.info("Original File Size: {} bytes", originalFileSize); + log.info("Optimized Image Dimensions: {}x{}", newWidth, newHeight); + log.info("Optimized File Size: {} bytes", optimizedFileSize); + + + return optimizedFile; + } + /** * 파일 타입을 결정하는 메소드. * diff --git a/src/main/java/ongjong/namanmoo/service/SharedFileService.java b/src/main/java/ongjong/namanmoo/service/SharedFileService.java index 0e5ed39..96cc1ee 100644 --- a/src/main/java/ongjong/namanmoo/service/SharedFileService.java +++ b/src/main/java/ongjong/namanmoo/service/SharedFileService.java @@ -10,6 +10,7 @@ import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.PutObjectRequest; import lombok.extern.slf4j.Slf4j; +import net.coobird.thumbnailator.Thumbnails; import ongjong.namanmoo.domain.*; import ongjong.namanmoo.domain.challenge.Challenge; import ongjong.namanmoo.dto.openAI.WhisperTranscriptionResponse; @@ -498,7 +499,12 @@ private void waitForImageUploadCompletion(int challengeNum, Lucky lucky) throws // 병합된 이미지를 S3에 업로드하는 메서드 public String uploadMergedImageToS3(BufferedImage mergedImage, String bucketName, String fileObjKeyName) throws IOException { + + // 최적화된 이미지로 변환 +// BufferedImage optimizedImage = optimizeImage(mergedImage); + ByteArrayOutputStream os = new ByteArrayOutputStream(); +// ImageIO.write(optimizedImage, "png", os); ImageIO.write(mergedImage, "png", os); byte[] buffer = os.toByteArray(); InputStream is = new ByteArrayInputStream(buffer); @@ -526,6 +532,43 @@ public String uploadMergedImageToS3(BufferedImage mergedImage, String bucketName } } +// /** +// * 이미지를 최적화하는 메소드. +// * +// * @param originalImage 최적화할 원본 이미지 +// * @return 최적화된 이미지 +// * @throws IOException 이미지 최적화 중 발생하는 예외 +// */ +// private BufferedImage optimizeImage(BufferedImage originalImage) throws IOException { +// int originalWidth = originalImage.getWidth(); +// int originalHeight = originalImage.getHeight(); +// +// // 원하는 최대 크기 설정 +// int maxWidth = (int) (originalWidth * 0.85); +// int maxHeight = (int) (originalHeight * 0.85); +// +// // 원본 비율 유지하며 크기 조정 +// double aspectRatio = (double) originalWidth / originalHeight; +// int newWidth = maxWidth; +// int newHeight = (int) (maxWidth / aspectRatio); +// if (newHeight > maxHeight) { +// newHeight = maxHeight; +// newWidth = (int) (maxHeight * aspectRatio); +// } +// +// // 이미지 리사이즈 및 압축 +// BufferedImage optimizedImage = Thumbnails.of(originalImage) +// .size(newWidth, newHeight) // 비율 유지하면서 리사이즈 +// .outputQuality(0.75) // 이미지 품질 설정 (0.0 ~ 1.0) +// .asBufferedImage(); +// +// log.info("Original Image Dimensions: {}x{}", originalImage.getWidth(), originalImage.getHeight()); +// log.info("Optimized Image Dimensions: {}x{}", optimizedImage.getWidth(), optimizedImage.getHeight()); +// +// +// return optimizedImage; +// } + // 특정 챌린지와 럭키 번호에 대한 이미지 결과를 가져오는 메서드 public Map> getFaceChallengeResults(int challengeNum, Long luckyId) { List sharedFiles = sharedFileRepository.findByChallengeNumAndLucky(challengeNum, luckyRepository.getLuckyByLuckyId(luckyId).get());