확장자는 JPG인데 Windows에서 열리지 않는 이미지 문제 해결한 방법

Window 운영체제에서 .jpg 확장자 이미지가 다운로드는 되지만 열리지 않는 문제를 해결한 과정을 공유합니다.
이번 문제는 안드로이드 폰에서 캡처한 이미지가 .jpg 확장자로 저장되었지만, 실제 내부 포맷은 AVIF였기 때문에 발생했습니다.
❗️ 문제 상황
Mac이나 Chrome 브라우저에서는 정상적으로 열리지만, 특정 Windows 환경에서는 이미지를 열 수 없는 문제가 발생했습니다.
🔍 문제 분석
터미널에서 문제가 된 이미지를 확인해보았습니다.

autowini2@autowiniui-MacBookPro-5 Desktop % file test.jpg
test.jpg: ISO Media, AVIF Image
autowini2@autowiniui-MacBookPro-5 Desktop % file umsungjun.jpg
umsungjun.jpg: JPEG image data, JFIF standard 1.01, resolution (DPCM), density 37x37, segment length 16, baseline, precision 8, 500x500, components 1- test.jpg → 확장자는 .jpg이지만, 실제 내부 포맷은 AVIF
- umsungjun.jpg → 정상적인 JPEG
원인
안드로이드에서 스크린샷을 찍으면, 기기 기본 설정에 따라 AVIF(또는 HEIF) 포맷으로 저장됩니다. 하지만 일부 환경에서는 파일 확장자를 .jpg로 강제로 붙이면서, 실제 포맷과 확장자가 불일치하는 문제가 발생합니다.
- AVIF: 최신 이미지 포맷으로, 압축 효율이 높고 화질 대비 용량이 작음. 안드로이드 최신 버전에서 기본 지원.
- JPEG: 오랜 기간 표준으로 쓰인 포맷. 대부분의 OS와 앱에서 호환 가능.
- Windows 기본 사진 앱: AVIF를 지원하지 않음 → 확장자는 .jpg인데 실제로는 AVIF라서 파일 손상 에러가 발생.
포맷이란?
포맷(format)이란, 이미지 데이터를 어떻게 압축·저장할지 정한 규격(파일 형식)을 말합니다.
- JPEG → 손실 압축, 높은 호환성
- PNG → 무손실 압축, 투명 배경 지원
- AVIF → 최신 규격, 높은 압축 효율
즉, 확장자 .jpg는 껍데기일 뿐이고, 내부에 저장된 실제 데이터가 어떤 포맷이냐에 따라 열 수 있느냐 없느냐가 결정됩니다.
✅ 해결 방법
안드로이드 캡처 이미지처럼 확장자는 .jpg인데 내부 포맷이 AVIF인 경우, Windows 기본 뷰어에서는 열리지 않는 문제가 발생했습니다.
이를 해결하기 위해, 다운로드 시 blob의 MIME 타입이 image/avif라면 Canvas를 통해 JPG로 변환 후 저장하도록 처리했습니다.
/**
* @description 파일 다운로드 함수
* @param url - 파일 URL
* @param filename - 다운로드할 파일 이름
*/
export const fileDownload = async (url: string, filename: string) => {
const res = await fetch(url);
if (!res.ok) throw new Error('파일 다운로드에 실패했습니다.');
const blob = await res.blob();
// avif → jpg 변환 (내부 MIME 타입이 avif일 때만 처리)
const convertIfAvif = async (blob: Blob): Promise<Blob> => {
if (blob.type === 'image/avif') {
const img = await createImageBitmap(blob);
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d');
if (!ctx) throw new Error('Canvas context 생성 실패');
ctx.drawImage(img, 0, 0);
return new Promise<Blob>((resolve, reject) => {
canvas.toBlob(
(newBlob) => {
if (newBlob) resolve(newBlob);
else reject(new Error('JPG 변환 실패'));
},
'image/jpeg',
0.9
);
});
}
return blob;
};
const finalBlob = await convertIfAvif(blob);
const objectUrl = URL.createObjectURL(finalBlob);
const link = document.createElement('a');
// 내부 포맷이 avif였다면 확장자를 jpg로 강제 변경
const finalFilename =
blob.type === 'image/avif'
? filename.replace(/\.[^/.]+$/, '') + '.jpg'
: filename;
link.href = objectUrl;
link.download = finalFilename || `file-${Date.now()}`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
// 메모리 해제
setTimeout(() => URL.revokeObjectURL(objectUrl), 100);
};💡 느낀 점
처음에는 단순히 “파일이 손상된 것 같다”라고만 생각했지만, 이번 경험을 통해 확장자와 실제 파일 포맷이 다를 수 있다는 점을 알게 되었습니다.
앞으로 유사한 문제가 발생하더라도, 보다 빠르게 원인을 파악하고 해결할 수 있을 것 같습니다.
- #avif
- #jpg
- #The photo cannot be opened because it is either in an unsupported format or corrupted.
- #Windows
- #버그해결
- #안드로이드
- #이미지포맷
- #현재 지원되지 않는 형식이거나 파일이 손상되었기 때문에 사진을 열 수 없습니다.