안드로이드 HEIC 이미지 업로드 이슈 해결기
최근 숙소 등록 기능에서 플랫폼에 따라 이미지 업로드가 다르게 작동하는 문제를 겪었다. 웹과 iOS에서는 문제가 없었는데, 안드로이드에서만 이미지 업로드 후 서버에서 썸네일을 생성하는 과정에서 에러가 발생했다.
처음에는 서버에 문제가 있다고 생각했다. 사용자가 이미지를 업로드하면, 서버에서는 sharp
라는 이미지 처리 라이브러리를 이용해서 썸네일을 생성하는데, 이때 아래와 같은 에러가 발생했다.
처음엔 단순히 업로드 도중 파일이 깨졌거나, sharp 설정 문제일 것이라고 생각했다. 그런데 이상한 점이 있었다. 사용자가 업로드한 건 HEIC 이미지였는데, 서버에 저장된 파일은 JPEG 포맷이었다. 변환이 어디서 일어났는지 추적이 필요했다.
원인 분석
프론트엔드 코드를 다시 확인해보니, 파일 입력 필드에 accept="image/*"
속성이 지정되어 있었다.
혹시 이게 브라우저에서 어떤 자동 처리를 유도하는 게 아닐까? 관련 키워드로 검색도 해보고, ChatGPT를 활용해 자료를 찾아보던 중, 일부 안드로이드 브라우저에서는 accept="image/*"
가 설정된 상태되어 있을 경우, 사용자가 HEIC 이미지를 선택하면 브라우저나 카메라 앱이 이를 자동으로 JPEG로 변환하여 업로드하는 경우가 있다는 걸 알게 되었다.
문제는 이렇게 변환된 JPEG 파일이 정상적인 이미지 포맷이 아닐 수 있다는 것이다. 변환 과정에서 메타데이터나 파일 구조가 깨지면서 sharp가 이 파일을 읽지 못하는 경우가 생긴다. 즉, 파일은 존재하지만 sharp가 읽을 수 없는 상태가 되어버리는 것이다.
해결 방법
가장 간단한 해결책은 accept
속성을 제거하는 것이었다.
제거한 뒤 테스트해보니, 안드로이드에서도 HEIC 원본 파일이 그대로 서버에 업로드되었고, 정상적으로 썸네일을 생성할 수 있었다.
새로운 고민
문제는 accept
속성을 없애면 이미지 외의 다른 파일도 사용자가 선택할 수 있다는 점이다. 이를 보완하기 위해 클라이언트에 업로드 하려는 파일의 MIME 타입을 검사해서, 이미지가 아닌 경우 업로드를 막는 처리를 추가했다.
이렇게 하면 적어도 이미지가 아닌 파일이 서버로 저장되는 걸 막을 수 있다. 사용자 경험 면에서는 조금 아쉬운 부분도 있지만, 안정성이 더 중요하다고 판단했다.
플랫폼별로 accept
속성을 다르게 설정하는 방법도 고민했었다. 하지만 플랫폼 감지 로직은 완벽하지 않기도 하고, 브라우저나 Webview 환경에 따라 다르게 작동할 수 있어 유지보수가 어려울 것 같았다. 또한 사용자 입장에서도 기기마다 파일 선택 UI나 허용되는 확장자가 달라지면 혼란을 줄 수 있다고 판단했다. 결국 모든 플랫폼에서 일관되게 동작하도록 하는 방향을 선택했다.
마무리
이번 이슈를 통해 느낀 점은 브라우저에 명시적으로 설정한 속성이 플랫폼에 따라 다르게 해석되거나, 의도치 않은 자동 처리를 유발할 수 있다는 점이다. 특히 이미지처럼 운영체제나 브라우저가 개입할 여지가 있는 기능에서는 예상하지 못한 문제가 발생할 수 있다는 걸 경험했다.
아직 완벽한 해결책이라고 생각하진 않는다. 클라이언트에서 이미지 포맷을 명확하게 확인하거나, 서버에서 HEIC 지원을 확대하는 방향도 향후 보완 과제로 남아 있다. 그래도 이번에는 문제의 원인을 정확히 파악하고, 가능한 선택지 중 가장 현실적인 대응을 했다는 점에서 좋은 경험이 되었다고 생각한다.