리사이징을 하게 된 계기
뭉치 프로젝트 특성상, 사진과 동영상 업로드의 횟수가 많다.
이때, S3 프리티어의 용량이 넘칠 것을 우려하여 업로드 전에 미리 리사이징 작업을 수행하도록 결정했다.
흐름
Marvin 의존성 추가
implementation 'com.github.downgoon:marvin:1.5.5'
implementation 'com.github.downgoon:MarvinPlugins:1.5.5'
Marvin 라이브러리를 사용할 것이기 때문에, marvin과 MarvinPlugins 의존성을 추가할 것이다.
리사이징 메서드
fun resizer(
fileName: String?,
fileFormat: String,
originalImage: MultipartFile,
width: Int
): MultipartFile {
return try {
val image = ImageIO.read(originalImage.inputStream)
val originWidth = image.width
val originHeight = image.height
if (originWidth < width) return originalImage
val imageMarvin = MarvinImage(image)
val scale = Scale()
scale.load()
scale.setAttribute("newWidth", width)
scale.setAttribute("newHeight", width * originHeight / originWidth)
scale.process(imageMarvin.clone(), imageMarvin, null, null, false)
val imageNoAlpha = imageMarvin.bufferedImageNoAlpha
val baos = ByteArrayOutputStream()
ImageIO.write(imageNoAlpha, fileFormat, baos)
baos.flush()
return CustomMultipartFile(fileName!!, fileFormat, originalImage.contentType, baos.toByteArray())
} catch (e: IOException) {
throw ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "파일을 줄이는데 실패했습니다.")
}
}
- marvin 라이브러리에서 생성자 요구사항이 BufferedImage 형태이므로 ImageIO.read를 활용하여 BufferedImage로 변경할 필요가 있다.
- 만약 원본파일의 width가 지정한 width보다 작으면 줄일 필요가 없으므로 원본파일의 width를 리턴한다.
- 리사이징 된 파일의 리턴값은 MultipartFile이어야 하므로 CustomMultipartFile이라는 클래스를 만든다.
업로드 파일 메서드
fun uploadFiles(files: List<MultipartFile>): List<String> {
val uploadedUrls = mutableListOf<String>()
for (file in files) {
try {
val fileName = file.originalFilename
val fileUrl = "<https://$>{bucket}.s3.ap-northeast-2.amazonaws.com/${fileName}"
val fileFormatName = getFileFormatName(file)
val resizedImage: MultipartFile = resizer(fileName, fileFormatName, file, 400)
val metadata = ObjectMetadata()
metadata.contentType = resizedImage.contentType
metadata.contentLength = resizedImage.size
amazonS3Client.putObject(bucket, fileName, resizedImage.inputStream, metadata)
uploadedUrls.add(fileUrl)
} catch (e: IOException) {
e.printStackTrace()
throw RuntimeException("File upload failed", e)
}
}
return uploadedUrls
}
뭉치 프로젝트는 한 유저가 여러 개의 사진과 동영상을 추가할 수 있기 때문에 반복문을 사용해 각 파일마다 리사이징을 하도록 구현하였다.
결과
눈에 띄게 작아진게 보인다.
'WEB' 카테고리의 다른 글
Redis Lock 동시성 해결하기 (0) | 2024.05.01 |
---|---|
인터셉터와 리졸버 (0) | 2024.04.12 |
JWT 활용기 (0) | 2024.04.12 |
Oauth를 사용해 카카오 로그인 구현 (0) | 2024.04.12 |
Spring Cloud Config 도입기 (0) | 2024.03.08 |
OAuth 2.0 동작 방식 (0) | 2023.06.05 |
JPA란 무엇일까? (0) | 2023.06.01 |
웹 서버와 웹 애플리케이션 서버 (0) | 2023.04.01 |