카페 후기 목록을 조회할 때 기존 방식은 첫번째 사진만 보여주는데 원본사진 그대로 보여주고 있었다
(상세 페이지에서 해당 게시물의 모든 사진을 보여준다)
하지만, 화면 렌더링 시간이 너무 오래 걸린다는 사용자의 의견이 있어
이를 개선하기 위해 썸네일을 만들기로 했다
카페 후기 목록에 보여줄 작은 사이즈의 저화질 사진을 원본 사진 파일로 만들어야 한다
코드의 일부만 본다면
//썸네일 resize하기
public BufferedImage resizeImage(File originalImage,
int targetWidth, int targetHeight)
throws IOException {
BufferedImage in = ImageIO.read(originalImage);
BufferedImage resizedImage =
new BufferedImage(targetWidth, targetHeight,
BufferedImage.TYPE_INT_RGB);
Graphics2D graphics2D = resizedImage.createGraphics();
graphics2D.drawImage(in, 0, 0, targetWidth, targetHeight, null);
graphics2D.dispose();
return resizedImage;
}
이미지 파일을 불러와 축소할 크기를 지정해주면서 이미지 파일을 새롭게 만들어낸다
코드에서는 가로 200, 세로 200으로 축소했다
로컬에서 여러 번의 테스트를 거치고, 개발 서버에서 RDS와 연결해 테스트를 해본 다음, 운영 서버에 반영했다
하지만, 여기서 문제가 생겼다
일부 썸네일이 회전되어 나타나고 있었다
진짜 모르겠더라...
그래도 원인을 분석하기 위해 썸네일이 회전되어 있는 게시물을 살펴봤다
회전되어있는 게시물에서 썸네일로 지정된 원본사진을 내려받아보았더니
정방형 사진이 아니고, 가로가 길거나 세로가 긴 사진들이었다
혹시 썸네일을 만들 때 원본 이미지를 정사각형으로 압축해서 사진이 회전되는건가? 라는 생각을 했다
검색을 해봤더니, 원본사진과 같은 비율로 사진을 줄이는 방법의 글이 있었다
//썸네일 축소 비율 정하기
//imageLength[0] : 가로, imageLength[1] : 세로
public int[] setImageRatio(BufferedImage bufferedImage) {
int[] imageLength = new int[2];
double ratio; // 이미지 축소 비율
int getWidth = bufferedImage.getWidth();
int getHeight = bufferedImage.getHeight();
if(getWidth < 250) ratio = 1;
else if(getWidth < 700) ratio = 2;
else if(getWidth < 1400) ratio = 5;
else ratio = 10;
int tWidth = (int) (getWidth / ratio); // 생성할 썸네일이미지의 너비
int tHeight = (int) (getHeight / ratio); // 생성할 썸네일이미지의 높이
imageLength[0] = tWidth; imageLength[1] = tHeight;
return imageLength;
}
간단했다
원본 사진의 실제 가로 길이와 세로 길이를 불러와서 가로/세로 모두 같은 숫자로 나눠 이미지를 줄이는 원리였다.
가로로 긴 사진과 세로로 긴 사진, 정방형 사진 등으로 테스트해본 결과 이런 길이일 때 이런 비율로 하자 라는 결론이 나왔다
if(getWidth < 250) ratio = 1;
else if(getWidth < 700) ratio = 2;
else if(getWidth < 1400) ratio = 5;
else ratio = 10;
여러 번의 테스트를 거치고, 운영 서버에 반영했지만 결과는 변함 없이 사진이 회전되어 나왔다..
이 추측이 틀렸으니, 이번엔 사진을 회전시키는 방법을 찾아봤다
https://wlsufld.tistory.com/112
위의 블로그 내용을 보면 사진의 메타데이터로 회전 정도인 'ORIENTATION' 값을 가져온다
ORIENTATION 정보를 가지고 이미지 파일을 원래대로 회전시켜 놓는다
여기서 Scalr 라이브러리가 쓰인다 (https://offbyone.tistory.com/114)
이렇게 해서 게시물을 작성할 때 썸네일이 회전되어 만들어지는 현상은 해결했다
하지만, 또 문제인 것은
코드가 적용된 이후로는 썸네일이 회전되어 나오지 않지만,
코드가 적용되기 전에 등록한 게시물에는 썸네일이 그대로 회전되어 있다
사용자가 게시물을 조회할 때 썸네일이 null이면 썸네일을 만들도록 로직을 짜 놓았기 때문에,
그 로직에 사진을 회전시키는 로직을 추가하면 될 것이라는 생각을 했다
그 로직에 회전시키는 로직을 적용했음에도 불구하고, 기존 썸네일은 변하지 않았다..
기존 이미지를 가지고 썸네일을 만드는 방법은
S3에 올라간 이미지 URL을 가지고 이미지 파일을 로컬에 만든 다음
그 파일을 가지고 썸네일 파일을 생성한 뒤 S3에 다시 올린다
// 로컬에 이미지 URL 파일 업로드 하기
private Optional<File> convert(String originalImageUrl) throws IOException {
URL url = new URL(originalImageUrl);
BufferedImage bufferedImage = ImageIO.read(url);
String fileName = originalImageUrl.substring(originalImageUrl.lastIndexOf("/") + 1);
File convertFile = getConvertFile(fileName);
if (convertFile.createNewFile()) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png", bos);
try (
FileOutputStream fos = new FileOutputStream(convertFile)) {
fos.write(bos.toByteArray());
}
return Optional.of(convertFile);
}
return Optional.empty();
}
//비율 유지하면서 썸네일 만들기
public BufferedImage resizeImage(String originalImageUrl) throws IOException {
Optional<File> optionalFile = convert(originalImageUrl);
if(optionalFile.isEmpty()) {
throw new CustomErrorException("섬네일 생성과정 실패");
}
File convertFile = optionalFile.get();
int orientation = getOrientation(convertFile);
BufferedImage in = rotateImage(convertFile, orientation);
//imageLength[0] : 가로, imageLength[1] : 세로
int[] imageLength = setImageRatio(in);
// 썸네일이미지
BufferedImage tImage = new BufferedImage(imageLength[0], imageLength[1],
BufferedImage.TYPE_3BYTE_BGR); // 썸네일이미지
Graphics2D graphic = tImage.createGraphics();
Image image = in.getScaledInstance(imageLength[0], imageLength[1], Image.SCALE_SMOOTH);
graphic.drawImage(image, 0, 0, imageLength[0], imageLength[1], null);
graphic.dispose(); // 리소스를 모두 해제;
return tImage;
}
디버그를 찍어봤더니, orientation 변수에 1이 담긴다
사진이 회전되어 있으면 1이 아닌 다를 숫자가 나와야 한다
즉, 사진은 회전되지 않았다는 말이다
눈으로 봤을 땐 회전되어 나오는데, 왜 컴퓨터는 회전되지 않았다는 건가!!!!!?!!??
추측으로는
이미지 파일 그 자체가 아닌 이미지 URL을 가지고 이미지 파일을 만들어냈기 때문에
메타데이터가 없는 것 같다
그래서 사진이 돌아가있는데도 orientation이 1이 나오는 것 같다
이렇게 된다면... 답이 없다
기존 게시물에 대해서는 해결할 수 없다
정보가 없는데 어떻게 해결하는가..!!!ㅠㅠ
어쩔 수 없이... "노가다"를 뛰었다
운영 서버에서 썸네일이 회전되어 있는 원본 사진을 일일이 다운받은 뒤,
로컬에서 프로젝트를 실행해 게시물 등록 API를 가지고 썸네일 URL을 얻어냈다
운영 서버에서 쓰이는 DB에 들어가서, 로컬에서 얻어낸 썸네일 URL로 한땀한땀 바꿔줬다
'항해99 3기' 카테고리의 다른 글
[TIL] 2021.12.03 최종 프로젝트 진행중 - 발표회 / 질문 꼭 대비하기 (0) | 2021.12.05 |
---|---|
[TIL] 2021.12.02 최종 프로젝트 진행중 - 오늘 해야할 일 (0) | 2021.12.02 |
[TIL] 2021.11.29 최종 프로젝트 진행중 - RDS 백업 및 복구 (1) | 2021.11.29 |
항해99 3기 15조 파이널 프로젝트 : 카페왕 (0) | 2021.11.29 |
[TIL] 2021.11.28 - 내일 꼭 해야할 일 (0) | 2021.11.29 |