[Spring Boot] 이미지 압축

미노·2024년 10월 16일

Spring Boot

목록 보기
1/1

들아가기 전에

10월 10일부터 'solve' 프로젝트를 시작했습니다.
'solve' 프로젝트는 백준과 비슷하게 코딩 테스트 문제를 풀 수 있는 사이트입니다.

https://github.com/NameOfTeam/solve-server

서버에서 유저 아바타를 수정할 때, PNG, JPG, WebP와 같은 다양한 이미지 형식으로 multipart file을 받아 처리합니다. 하지만 파일을 저장할 때는 모든 이미지를 하나의 확장자인 WebP로 변환하여 저장하게 만들었습니다. 이를 통해 유저 엔티티에 avatar_url을 저장할 필요 없이 https://서버주소/avatars/{userId}.{확장자} 로 접근 가능하도록 하였습니다.

뭘로 압축하지?

이미지 압축 방식에는 png, jpeg, webp등 다양하게 있습니다.

PNG: 무손실 압축, 파일 크기 큼, 투명도 지원
JPEG: 손실 압축, 파일 크기 작음, 투명도 없음
WebP: 손실/무손실 압축 지원, 작은 파일 크기와 높은 품질, 투명도 지원

이번 프로젝트에서는 webp로 압축하는 것으로 결정하였습니다.

왜? 무손실 압축이 가능하며, 파일 크기가 작기 때문에 웹사이트 이미지에 최적화 되어있다고 생각했기 때문입니다.

압축 구현하기

라이브러리는 scrimage를 사용하기로 결정하였습니다.

의존성 추가

implementation("com.sksamuel.scrimage:scrimage-core:4.2.0")
implementation("com.sksamuel.scrimage:scrimage-webp:4.2.0")

압축 코드 (256x256)

val png = File(directory, "${user.id}.png")

file.transferTo(png)

ImmutableImage.loader()
	.fromFile(png)
	.scaleTo(256, 256)
    .output(WebpWriter.DEFAULT.withLossless(), File(directory, "${user.id}.webp"))
    
png.delete()

file은 request에서 받아온 MultipartFile이고, directory는 사용자 프로필 사진을 저장할 위치이며, user.id는 유저의 아이디입니다.

원본 이미지

압축된 이미지

해당 코드를 적용한 결과 만족스러운 이미지 압축이 완성되었고 팀원과 상의 끝에 이를 적용하기로 결정하였습니다.

마무리

사실 너무 라이브러리에 의존하여 쉽게 만든 것이 아닌가 걱정됩니다.
다음에는 직접 ImageIO와 같은 것을 건드려서 이미지를 압축해보고 싶습니다.

profile
백엔드 공부하는 학생

0개의 댓글