Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

webp 파일로 변환하여 이미지 파일 크기 최적화 #312

Merged
merged 3 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ dependencies {

//elastic search
implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch'

//webp
implementation 'com.sksamuel.scrimage:scrimage-core:4.2.0'
implementation 'com.sksamuel.scrimage:scrimage-webp:4.2.0'
}

test {
Expand Down
62 changes: 48 additions & 14 deletions src/main/java/com/konggogi/veganlife/global/AwsS3Uploader.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
import com.konggogi.veganlife.global.domain.AwsS3Folders;
import com.konggogi.veganlife.global.exception.ErrorCode;
import com.konggogi.veganlife.global.exception.FileUploadException;
import com.sksamuel.scrimage.ImmutableImage;
import com.sksamuel.scrimage.webp.WebpWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.nio.file.Files;
import java.util.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
Expand Down Expand Up @@ -47,15 +49,19 @@ public String uploadFile(AwsS3Folders uploadFolder, MultipartFile multipartFile)
return null;
}
String newFileName = uploadFolder.getName() + generateRandomFilename(multipartFile);
File file = convertMultipartFileToFile(multipartFile);
File webpFile = convertFileToWebp(file);

ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(multipartFile.getSize());
metadata.setContentType(multipartFile.getContentType());
metadata.setContentLength(webpFile.length());
metadata.setContentType("image/webp");

try {
amazonS3.putObject(bucket, newFileName, multipartFile.getInputStream(), metadata);
try (FileInputStream fileInputStream = new FileInputStream(webpFile)) {
amazonS3.putObject(bucket, newFileName, fileInputStream, metadata);
} catch (SdkClientException | IOException e) {
throw new FileUploadException(ErrorCode.FILE_UPLOAD_ERROR);
} finally {
deleteTempFiles(file, webpFile);
}
return cloudfrontDomain + newFileName;
}
Expand All @@ -65,18 +71,46 @@ private String generateRandomFilename(MultipartFile multipartFile) {
if (originalFileName == null) {
throw new FileUploadException(ErrorCode.NULL_FILE_NAME);
}
String extension = validateFileExtension(originalFileName);
return UUID.randomUUID() + "." + extension;
validateFileExtension(originalFileName);
return UUID.randomUUID() + ".webp";
}

private String validateFileExtension(String originalFilename) {
private void validateFileExtension(String originalFilename) {
String fileExtension =
originalFilename.substring(originalFilename.lastIndexOf(".") + 1).toLowerCase();
List<String> allowedExtensions = Arrays.asList("jpg", "png", "gif", "jpeg", "webp");
List<String> allowedExtensions = Arrays.asList("jpg", "png", "jpeg", "webp");

if (!allowedExtensions.contains(fileExtension)) {
throw new FileUploadException(ErrorCode.INVALID_EXTENSION);
}
return fileExtension;
}

private File convertMultipartFileToFile(MultipartFile multipartFile) {
File file = new File(multipartFile.getOriginalFilename());
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(multipartFile.getBytes());
return file;
} catch (IOException e) {
throw new FileUploadException(ErrorCode.FILE_CONVERT_ERROR);
}
}

private File convertFileToWebp(File file) {
File outputFile = new File("resize_" + System.currentTimeMillis() + ".webp");
try {
return ImmutableImage.loader().fromFile(file).output(WebpWriter.DEFAULT, outputFile);
} catch (IOException e) {
throw new FileUploadException(ErrorCode.FILE_CONVERT_ERROR);
}
}

private void deleteTempFiles(File... files) {
for (File file : files) {
try {
Files.deleteIfExists(file.toPath());
} catch (IOException e) {
throw new FileUploadException(ErrorCode.FILE_DELETE_ERROR);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,10 @@ public enum ErrorCode {
// file-upload
MAX_UPLOAD_SIZE_EXCEEDED("FILE_UPLOAD_001", "파일 크기 제한(10MB)을 초과한 파일입니다."),
NULL_FILE_NAME("FILE_UPLOAD_002", "파일 이름은 null일 수 없습니다."),
INVALID_EXTENSION("FILE_UPLOAD_003", "유효한 이미지 파일 확장자(jpg, png, gif, jpeg)가 아닙니다."),
FILE_UPLOAD_ERROR("FILE_UPLOAD_004", "파일을 업로드 하는 중 에러가 발생했습니다."),
INVALID_EXTENSION("FILE_UPLOAD_003", "유효한 이미지 파일 확장자(jpg, png, jpeg, webp)가 아닙니다."),
FILE_CONVERT_ERROR("FILE_UPLOAD_004", "파일을 변환 하는 중 에러가 발생했습니다."),
FILE_UPLOAD_ERROR("FILE_UPLOAD_005", "파일을 업로드 하는 중 에러가 발생했습니다."),
FILE_DELETE_ERROR("FILE_UPLOAD_006", "임시 파일을 삭제 하는 중 에러가 발생했습니다."),

// elastic search
ES_OPERATION_FAILED("ELASTIC_SEARCH_001", "검색 작업 도중 오류가 발생했습니다.");
Expand Down
Loading