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

이미지 파일 업로드 시 회전 버그 해결 #367

Merged
merged 5 commits into from
Jun 8, 2024
Merged

Conversation

mingmingmon
Copy link
Collaborator

Summary

#358

이미지 파일 업로드 시 촬영 각도에 따라 회전하는 버그를 해결했습니다.

Tasks

  • 필요한 의존성을 추가하고 전송된 multipartfile의 회전정보에 따라
    적절하게 다시 회전 후 서버에 이미지를 저장합니다.

ETC

Screenshot

image

@mingmingmon mingmingmon added the 🐞 Bug 버그 제보 및 수정 label Jun 6, 2024
@mingmingmon mingmingmon requested a review from limehee June 6, 2024 16:57
@mingmingmon mingmingmon self-assigned this Jun 6, 2024
@mingmingmon mingmingmon changed the title fix: 이미지 파일 업로드 시 회전 버그 해결 #358 이미지 파일 업로드 시 회전 버그 해결 Jun 6, 2024
@limehee
Copy link
Collaborator

limehee commented Jun 6, 2024

public int getImageDirection(File tempFile) {
    int originalDirection = 1;
    try {
        Metadata metadata = ImageMetadataReader.readMetadata(tempFile);
        Directory directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
        if (directory != null) {
            originalDirection = directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
        }
    } catch (Exception e) {
        originalDirection = 1;
    }
    return originalDirection;
}

메소드 시작부에서 originalDirection은 이미 1로 초기화되었지만, 예외가 발생했을 때 다시 한 번 1로 초기화하고 있습니다.
예외 상황에서 originalDirection의 값은 1로 유지될 것으로 보이는데, 값을 재설정한 이유가 있을까요?

@limehee
Copy link
Collaborator

limehee commented Jun 6, 2024

파일 포맷과 무관하게 multipartFile.transferTo()를 통해 업로드되던 로직이 다음과 같이 수정되었습니다.

try {
    BufferedImage originalImage = adjustImageDirection(multipartFile);
    ImageIO.write(originalImage, extension, file);
} catch (Exception e) {
    throw new IOException("이미지의 뱡향을 조정하는데 오류가 발생했습니다.", e);
}

수정된 코드는 이미지 파일이 아닌 경우에도 adjustImageDirection(), ImageIO.write() 메소드를 호출하여 파일을 처리합니다.
이미지 회전 오류를 해결하기 위해 로직을 잘 작성하였다고 판단되나, 이미지 외의 파일일 경우 불필요한 연산의 증가, 파일 포맷에 따른 예외 발생 가능성이 있다고 여겨집니다. 이미지 파일일 경우에만 해당 로직이 적용되도록 변경하는 것을 제안합니다.

import org.springframework.web.multipart.MultipartFile;

private boolean isImageFile(MultipartFile file) {
    String contentType = file.getContentType();
    return contentType != null && contentType.startsWith("image/");
}

MultipartFile의 contentType을 이용하여 이미지 파일을 식별하는 코드입니다. 참고 바랍니다.

@limehee limehee linked an issue Jun 6, 2024 that may be closed by this pull request
@SongJaeHoonn
Copy link
Contributor

SongJaeHoonn commented Jun 7, 2024

발생된 버그에 맞춰 프로젝트에 알맞은 의존성을 추가해서 문제를 해결해나가는 과정이 정말 인상적이었습니다!
다음 코드에서, 설정한 이미지의 메타데이터인 originalDirection을 가져와서 이미지가 회전되어 저장될 때 직접 방향을 바꿔주는 방식으로 구현하셨습니다.

switch (originalDirection) {
    case 1:
        break;
    case 3:
        bufferedImage = Scalr.rotate(bufferedImage, Scalr.Rotation.CW_180, null);
        break;
    case 6:
        bufferedImage = Scalr.rotate(bufferedImage, Scalr.Rotation.CW_90, null);
        break;
    case 8:
        bufferedImage = Scalr.rotate(bufferedImage, Scalr.Rotation.CW_270, null);
        break;
}

다만 이미지가 회전되는 현상에서 originalDirection의 범위를 1, 3, 6, 8번으로만 제한하신 이유가 궁금합니다!
회전 버그 발생이 이 네 가지 상황으로만 발생하는 것인가요?

@mingmingmon
Copy link
Collaborator Author

@limehee

  1. 예외처리 시, catch문에서 originalDirection을 다시 1로 설정한 것은 참고한 코드에서 작성된 부분이었는데요. 짚어주신 덕분에 굳이 불필요한 코드 대신 해당 함수 내에서 발생할 수 있는 예외들로 catch문을 수정했습니다! 감사합니다.

  2. 이미지 파일만 회전방향을 수정하는 메소드를 거치도록 수정하였습니다! 이미지 파일이 아닌 것들을 바로 transferTo 메소드로 저장할 수 있도록 했습니다.

@mingmingmon
Copy link
Collaborator Author

@SongJaeHoonn
저도 작업할 때 이 부분에 대해서 의문점을 가지고 찾아본 결과, 회전관련 문제는 1,3,6,8 인 경우이고, 나머지 값들은 주로 미러링(뒤집기)와 관련되어 있었습니다.

이런 미러링이 orientation으로 기록되는 것은 셀카모드가 가장 대표적인 예시인데요. 거울과 같은 원리로 좌우가 뒤집어져 보이는 화면을 사용자가 보게 됩니다. 이를 처리하는 로직은 switch문에 명시할 때와, 하지 않을 때 모두 문제 없이 휴대폰에 저장된 원본 사진과 같은 이미지로 보여 따로 추가해주지 않았습니다!

생각해보니, 저도 궁금해서 찾아봤던 부분이고, 제3자가 읽을 때도 질문이 생길 수 있는 부분인 것 같은데, 블로그에 언급하지 않았었네요.. 해당 내용 추가해서 정리해두겠습니다! 짚어주셔서 감사합니다!

@mingmingmon
Copy link
Collaborator Author

추가로 사용자가 의도적으로 회전을 일으킨 경우 잘 저장되는지에 대한 테스트 결과를 첨부합니다!

왼쪽이 원본사진, 오른쪽이 저장된 사진입니다.

image

@limehee limehee requested a review from SongJaeHoonn June 8, 2024 16:25
@limehee limehee merged commit 913e310 into develop Jun 8, 2024
1 check passed
@limehee limehee deleted the bug/#358 branch June 8, 2024 16:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐞 Bug 버그 제보 및 수정
Projects
None yet
Development

Successfully merging this pull request may close these issues.

이미지 파일을 업로드 시 회전해서 저장되는 버그
3 participants