읽기에 앞서

버그 발견!!

  • 이미지 리사이징을 적용한 후 중대한 버그를 발견하게 되었다.

리사이징버그

  • png 타입의 이미지를 등록하는 경우 이렇게 이미지가 깨져버린다. (S3에 보면 0B로 용량도 없음)

  • jpg의 타입을 등록하면 정상적으로 동작하는데 해결을 한 지금 시점까지도 사실 정확한 버그 이유와 해결 방법을 알지 못한다.

  • StackOverFlow 참고

    public static MultipartFile getResizedMultipartFile(MultipartFile multipartFile, String originalFileName) throws IOException {
            final int TARGET_IMAGE_WIDTH = 450;
            final int TARGET_IMAGE_HEIGHT = 450;
            final String IMAGE_TYPE = "jpg";
      
            BufferedImage bi = ImageIO.read(multipartFile.getInputStream());
            bi = resizeImages(bi, TARGET_IMAGE_WIDTH, TARGET_IMAGE_HEIGHT);
      
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            boolean check = ImageIO.write(bi, IMAGE_TYPE, baos);
      
            log.info("check={}",check);
      
            baos.flush();
      
            return new CustomMultipartFile(baos.toByteArray(), multipartFile.getName(), originalFileName, "image/*", false, baos.toByteArray().length);
        }
    
  • 위의 게시글과 기존의 내 코드를 따르면 ImageIO에서 wrtie 타입을 jpg로 설정해줬다. 하지만 OpenJDK가 JPEG Encoder를 지원하지 않기 때문에 png 파일을 입력받으면 동작하지 않는다고 한다.

  • ImageIO.write의 결괏값이 false로 나옴

리사이징버그

  • 이를 해결하기 위해 새로운 BufferedImage의 imageType을 변경하여 만들어도 보는 등 다양한 방식을 시도해봤으나 그냥 검은색 이미지가 만들어지거나 색이 흑백으로 나오는 등 문제가 많았다.

  • 시행착오 끝에 선택한 해결법은 ImageIo.wrtie를 하는 시점에 IMAGE_TYPE을 png로 설정하는 것이었다.

    public static MultipartFile getResizedMultipartFile(MultipartFile multipartFile, String originalFileName) throws IOException {
            final int TARGET_IMAGE_WIDTH = 450;
            final int TARGET_IMAGE_HEIGHT = 450;
            final String IMAGE_TYPE = "png";              // 달라진 부분
      
            BufferedImage bi = ImageIO.read(multipartFile.getInputStream());
            bi = resizeImages(bi, TARGET_IMAGE_WIDTH, TARGET_IMAGE_HEIGHT);
      
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            boolean check = ImageIO.write(bi, IMAGE_TYPE, baos);
      
            log.info("check={}",check);
      
            baos.flush();
      
            return new CustomMultipartFile(baos.toByteArray(), multipartFile.getName(), originalFileName, "image/*", false, baos.toByteArray().length);
        }
    
  • 결괏값이 true로 나옴

리사이징버그

결론

  • 이 문제는 내부적인 Image 처리 방법과 PNGJPG의 차이같은 이미지 파일별 특징 및 차이를 파악해야 확실하게 이해가 가능할 것 같습니다.
  • 또한, IMAGE_TYPE을 png로 설정하였다는 이유 만으로 왜 모든 이미지에 대한 처리가 해결되는지 의문점이 크게 남았습니다.
  • 현재 제 프로젝트에서 png를 사용하나 jpg를 사용하나 아무런 문제가 없고 새로운 BufferedImage를 생성하여 이를 jpg로 변환하여 업로드하는 과정보다 그냥 java의 png encoder를 활용하여 png, jpg 둘 다 처리할 수 있는 최종적인 해결법이 가장 적절하다고 생각하여 이를 사용하여 버그를 해결하였습니다.

댓글남기기