위에서 파일을 고르면 바로 열립니다.준비됨 — 인터넷을 끊어도 이대로 동작합니다.이 브라우저에서는 쓸 수 없습니다 (나머지는 그대로 동작합니다).오프라인 저장에는 https:// 또는 localhost가 필요합니다.여기서는 저장할 수 없지만, 어느 쪽이든 올라가는 것은 없습니다.파일은 어디로도 가지 않았습니다. 파일 {total}개를 불러왔고 모두 이 사이트의 것입니다. {platform}무언가가 {hosts}에 접속했는데, 이 도구는 절대 그러지 않습니다. 살펴볼 만합니다. {platform}광고와 측정과 후원 버튼을 위한 이 사이트 자신의 스크립트가 호스트 {hosts}곳에서 왔습니다. 그중 어느 쪽도 파일이나 그 1바이트도 받지 않았습니다.광고와 측정과 후원 버튼을 위한 이 사이트 자신의 스크립트가 호스트 {hosts}곳에서 왔습니다. 그중 어느 쪽도 파일이나 그 1바이트도 받지 않았습니다.문제가 생겼습니다: {detail}. 처음부터 다시 하려면 페이지를 새로 고치세요.파일 {count}개를 읽는 중…파일 {count}개를 읽는 중…예시로 해 보기예시를 만드는 중…이 브라우저에서는 예시를 만들지 못했습니다. 대신 파일을 골라 주세요.
디코딩은 내 브라우저가 내 기기의 성능으로 합니다. HEIC는 브라우저가 혼자서는 열지 못하는 유일한 사진 형식이라, 이 페이지가 디코더를 함께 싣고 옵니다. 1.4 MB쯤 되고, 이 사이트에서 제공되며, 첫 방문 이후에는 캐시됩니다. 다른 HEIC 변환기가 하나같이 업로드를 요구하는 이유가 바로 이것입니다. 코덱을 서버에 두었으니 사진이 거기까지 가야 하는 거죠. 이 도구는 코덱을 대신 여기에 둡니다. 이 페이지에는 네트워크 기능이 아예 없고, 반대편에 사진을 받아 줄 서버도 없습니다.
✗ 업로드 없음
✗ 가입 없음
✗ 용량 제한 없음
✓ 오프라인 동작
✓ 오픈 소스
실시간 확인:확인 중…
오프라인:확인 중…
그냥 믿지 마시고 직접 확인해 보세요. 개발자 도구의 '네트워크' 탭을 켜 놓고 사진을 변환해 보십시오. 이 페이지 자신의 파일들이 불려 오는 것이 보이고 그중에 디코더도 있겠지만, 사진이나 미리보기, 파일 이름, 고른 파일의 단 1바이트를 실어 나르는 요청은 하나도 없습니다. 아니면 페이지를 한 번 불러온 뒤 인터넷을 끊고 폴더 하나를 통째로 변환해 보셔도 됩니다.
이 약속을 직접 확인하는 방법
사진은 나갈 곳이 없습니다. 이 페이지가 연결해도 되는 주소는 Content-Security-Policy에 모두 적혀 있는데, 그중 이 사이트 것은 하나도 없습니다. 파일이 모일 만한 수신 지점이 없고, 설령 있더라도 거기로 파일을 보낼 코드가 없습니다.
디코더는 여기서 왔고, 어디로도 가지 않습니다. HEIC는 박스 형식에 담긴 HEVC이고 Safari 말고는 어떤 브라우저도 디코딩하지 못합니다. 그래서 이 페이지가 WebAssembly로 컴파일한 libheif를 싣고 옵니다. 1.4 MB쯤 되고, 이 저장소에 커밋되어 있고, 이 출처에서 제공되며, 여기 다른 파일들과 똑같이 서비스 워커가 캐시합니다. CDN에서 가져오지 않습니다. 그러면 모든 방문 경로에 제삼자가 끼어들고 오프라인 동작도 멈추니까요. 바이너리를 스크립트 옆이 아니라 안에 넣어 둔 것도 정확히 같은 이유입니다. 시작하는 데 요청이 필요 없도록요.
여기서는 아무것도 가져오지 않습니다. 이 도구를 위해 쓴 파일 어디에도 fetch도, XMLHttpRequest도, sendBeacon도 없습니다. 싣고 온 엔진에는 모든 Emscripten 빌드가 그렇듯 .wasm을 주소에서 가져오는 로더 경로가 들어 있지만, 그 길로는 가지 않습니다. 바이너리를 이미 손에 쥐고 있으니까요. 설령 간다 해도 connect-src에는 구글의 측정 엔드포인트 말고 아무것도 적혀 있지 않아 브라우저가 거부합니다. 증거는 약속이 아니라 정책입니다.
메타데이터는 여기서 읽어 화면에 보여 드립니다. 페이지의 목록이 각 사진에 무엇이 담겨 있는지 말해 줍니다. 날짜, 카메라, 그리고 GPS 좌표가 들어 있는지까지요. JPEG를 누군가에게 건네기 전에 알고 싶은 것들이니까요. 그걸 파일에서 읽는 것은 이 브라우저 안의 src/boxes.js이고, 결과는 이 페이지에 표시되며, JPEG에 쓸지 뺄지는 전적으로 고르시기 나름입니다. 이 저장소에는 파일 이름이나 날짜, 좌표, 개수를 실어 보내는 분석 이벤트가 하나도 없습니다.
구글이 불러오는 것과, 구글에게 주지 않는 것. 광고와 측정 스크립트는 구글에서, 후원 버튼은 Buy Me a Coffee에서 옵니다. 어느 쪽에도 내 사진에 관한 것은 넘어가지 않습니다. 파일을 읽고 디코딩하고 쓰는 코드는 한 줄도 빠짐없이 이 출처에서 제공되고 저장소에 공개되어 있습니다.
오프라인에서도 동작합니다. 페이지를 한 번 불러온 뒤 네트워크를 끊어도 도구는 그대로입니다. 디코더도 함께 캐시되어 있으니까요. 가장 간단한 증거이고, 이 사이트의 다른 어디보다 여기서 더 강한 증거입니다. 사진을 어딘가로 보내서 디코딩하는 변환기라면 결코 해낼 수 없는 일이니까요.
직접 확인해 보세요. 위에 적은 어느 것도 그냥 믿으실 필요는 없습니다. 이 페이지는 저장소 안의 템플릿과 설정을 빌드 스크립트가 찍어 낸 결과이고, 그 스크립트는 누구나 읽고 직접 돌려 볼 수 있습니다. 결과물은 dist 브랜치에 그대로 올라가 있고요. 그래서 실제로 제공되는 파일과 소스를 빌드한 결과를 나란히 놓고 비교해 보실 수 있습니다:
먼저 읽어 볼 파일을 꼽자면, Content-Security-Policy는 config/site.toml, 디코더를 어떻게 불러오고 무엇까지 허용하는지는 src/heif.js, 사진의 메타데이터를 찾아내는 컨테이너 해석은 src/boxes.js, 그 메타데이터가 JPEG로 들어가는 길에 겪는 일은 src/exif.js에 있습니다. 엔진 자체는 손대지 않은 vendor/libheif.js이고, 라이선스가 그 옆에 있습니다.
회사 보안 소프트웨어가 업로드를 경고한다면. 그것은 브라우저에서 파일이 선택되는 순간을 지켜보며, 페이지가 그것을 보낼 생각인지는 알 수 없습니다 — 그래서 고르는 순간에 경고합니다. 여기서는 아무것도 보내지 않습니다. 브라우저 개발자 도구를 열고 네트워크 탭으로 옮긴 뒤 파일을 골라 보세요. 그것을 실어 나르는 요청은 없고, 이 페이지 자체의 로컬 미리보기 말고는 요청 자체가 없습니다. 같은 확인을 IT 팀도 삼십 초면 할 수 있습니다.
1 HEIC 사진 고르기
휴대폰에서 바로 꺼낸 것이든, 백업에서 나온 것이든, 메모리 카드에서 복사한 것이든 좋습니다. 파일을 읽는 것도 여기, 이 기기이고, 사진을 디코딩하는 것도 여기입니다 — 이 페이지에는 업로드 단계가 없고 뒤에 서버도 없습니다.
2 무엇을 돌려받을지 정하기
날짜와 카메라, 설정 유지 휴대폰이 쓴 그대로 옮기기 때문에, 변환한 사진이 변환한 날이 아니라 찍은 날 기준으로 정렬됩니다. 사진에 GPS 좌표가 있다면 그것도 함께 갑니다. 어느 사진이 그런지는 위 목록에 적혀 있고요. 이 항목을 끄면 JPEG에는 사진 말고 아무것도 들어가지 않습니다.
어느 쪽을 고르든 여기서 누군가에게 읽혀 나가는 것은 없습니다. 이 선택이 정하는 것은 돌려받는 파일에 무엇이 들어가느냐이지, 이 페이지가 그걸로 무엇을 하느냐가 아닙니다. 태그를 자세히 들여다보거나 이미 JPEG인 사진에서 태그를 지우고 싶다면 EXIF 확인 및 제거가 그 일을 하는 도구입니다.
3 변환
변환 완료
{name}: {why}이것은 HEIC가 아니라 AVIF입니다. 요즘 브라우저는 모두 이미 열 수 있으니 여기서 해 줄 일이 없습니다.이것은 이미 JPEG입니다.이것은 PNG이고, 이미 어디서나 열립니다.이것은 HEIC가 아닙니다. {name}이(가) 무엇이든 그 앞부분 바이트는 HEIF 컨테이너가 아니고, 이름도 증거가 되지 않습니다.사진 {n}장, 모두 {size}사진 {n}장, 모두 {size}HEIC ({brand}) · {size}{name}을(를) 목록에서 빼기이 파일에는 사진 정보가 없습니다GPS 좌표사진 정보는 있지만 신원을 알 만한 것은 없습니다{a} · {b}{a} {b}JPEG는 부탁했더라면 휴대폰이 썼을 형식입니다. 어떤 프로그램도, 어떤 웹사이트도, 어떤 프린터도 엽니다.PNG는 아무것도 버리지 않고, 사진을 이것으로 저장하면 보통 JPEG의 다섯 배에서 열 배가 됩니다. 화면 갈무리나 도표에는 맞고 휴가 사진에는 맞지 않는 선택입니다.WebP는 같은 품질에서 JPEG보다 작고 2020년 이후에 나온 브라우저라면 모두 엽니다 — 다만 데스크톱 프로그램이 모두 그런 것은 아니어서, 누군가에게 보내기 전에 확인할 것이 바로 그 점입니다.날짜와 카메라와 위치는 빠집니다.날짜와 카메라와 위치가 그대로 옮겨 가고, 회전 태그는 바로잡힙니다. 사진 자체가 이미 바른 방향으로 돌려졌기 때문입니다.사진 정보는 함께 갈 수 없습니다. 캔버스가 쓸 수 있는 표준 자리를 가진 것은 JPEG뿐이라서, {format} 파일은 사진만 담고 나옵니다.파일새 형식WebP — 이 브라우저는 지원하지 않습니다디코더를 기다리는 중읽는 중디코딩 중{total}장 중 {index}번째 사진을 쓰는 중{format}을(를) 쓰는 중{total}개 중 {index}번째: {name} — {note}디코더가 불러와지지 않았습니다. 이 사이트에서 내려 주는 것이므로 요청이 막혔거나 첫 방문이 잘못된 것입니다 — 새로 고치면 대개 해결됩니다.디코더는 불러와졌지만 시작하지 않았습니다.디코더가 이 파일을 읽지 못했습니다({detail}).이 파일에는 디코더가 찾을 수 있는 사진이 없습니다.이 파일의 사진에는 디코더가 쓸 수 있는 크기가 없습니다.디코더가 파일은 읽었지만 그리지는 못했습니다.이 브라우저가 {format}을(를) 써 주지 않았습니다.HEIC 파일 {n}개HEIC 파일 {n}개{format} 사진 {n}장{format} 사진 {n}장{files} → {pictures}. {before} → {after}, {change}.변환된 사진: {name}{before} → {after} · {change}내려받기{size} 크기의 {format}품질 {n}파일 안의 {total}장 중 {n}번째 사진사진 정보 유지사진 정보 유지, GPS 좌표 포함사진 정보를 쓰지 않음사진 정보가 JPEG 구획에 넣기에 너무 커서 빠졌습니다{list}.거의 같은 크기{n}% 작아짐{n}% 커짐{n}바이트{n} KB{n} MBHEIC 디코더는 처음 쓸 때 이 사이트에서 내려옵니다. 약 1.4 MB, 한 번뿐이고 그다음부터는 캐시에 남습니다.HEIC 디코더를 이 사이트에서 내려받는 중: 약 1.4 MB, 한 번뿐입니다.디코더 준비 완료 — 이 사이트에서 내려온 뒤 캐시에 남아 다음에도, 네트워크를 뽑아 두어도 여기 있습니다.디코더를 시작하지 못했습니다: {why}{total}개 중 {done}개까지 하고 멈췄습니다. 끝난 것은 아래에 있습니다.첫 번째가 끝나기 전에 멈췄습니다.준비됨 — 디코더까지 함께 저장되므로 네트워크를 뽑아도 동작합니다.사진은 어디로도 가지 않았습니다. 파일 {total}개를 불러왔고 모두 이 사이트의 것입니다. 디코더도 그 안에 있습니다. {platform}무언가가 {hosts}에 접속했는데, 이 도구는 절대 그러지 않습니다. 살펴볼 만합니다. {platform}광고와 측정과 후원 버튼을 위한 이 사이트 자신의 스크립트가 호스트 {hosts}곳에서 왔습니다. 그중 어느 쪽도 사진이나 그 1바이트도 받지 않았습니다.광고와 측정과 후원 버튼을 위한 이 사이트 자신의 스크립트가 호스트 {hosts}곳에서 왔습니다. 그중 어느 쪽도 사진이나 그 1바이트도 받지 않았습니다.
원하는 결과가 나왔나요?
무엇이 잘못됐나요?
고맙습니다 — 큰 도움이 됩니다.
보내지는 것은 답변뿐이고, 그것도 버튼을 눌렀을 때만입니다. 파일도, 파일 이름도, 파일에 관한 어떤 정보도 보내지 않습니다.
# HEIC를 JPG로 — 아이폰 사진 변환
아이폰이 만드는 사진을, 아무 데서나 열리는 형식으로.
> 아이폰 HEIC 사진을 브라우저에서 JPG로 바꿉니다. 디코더가 내 기기에서 돕니다. 업로드 없음, 가입 없음, 오프라인 동작, 촬영 날짜와 카메라 정보도 함께 옮길 수 있습니다.
이 페이지는 브라우저 안에서만 동작하는 대화형 도구입니다(https://abox.tools/ko/heic-jpg-변환/). 도구에 넘긴 어떤 것도 업로드되지 않습니다. 아래는 이 페이지가 도구에 대해 글로 설명하는 내용 전부입니다. 도구를 쓰려면 이 주소를 여세요.
## 사진은 **절대 업로드되지 않습니다**. 서버가 아예 없으니까요.
디코딩은 내 브라우저가 내 기기의 성능으로 합니다. HEIC는 브라우저가 혼자서는 열지 못하는 유일한 사진 형식이라, 이 페이지가 디코더를 함께 싣고 옵니다. 1.4 MB쯤 되고, 이 사이트에서 제공되며, 첫 방문 이후에는 캐시됩니다. 다른 HEIC 변환기가 하나같이 업로드를 요구하는 이유가 바로 이것입니다. 코덱을 서버에 두었으니 사진이 거기까지 가야 하는 거죠. 이 도구는 코덱을 대신 여기에 둡니다. 이 페이지에는 네트워크 기능이 아예 없고, 반대편에 사진을 받아 줄 서버도 없습니다.
- ✗ 업로드 없음
- ✗ 가입 없음
- ✗ 용량 제한 없음
- ✓ 오프라인 동작
- ✓ 오픈 소스
## HEIC 사진을 JPG로 바꾸는 방법
1. **HEIC 사진을 고릅니다.** 휴대폰 백업이든 바탕화면 폴더든, 선택 영역에 끌어다 놓거나 직접 골라 주세요. 브라우저가 디스크에서 읽고, 그동안 어디로도 아무것도 나가지 않습니다. 목록에 각 파일이 무엇이고 안에 무엇이 들었는지가 적힙니다.
2. **사진이 무엇을 담고 있는지 확인합니다.** 각 줄에 촬영 날짜와 카메라가 적히고, 그 파일에 GPS 좌표가 들어 있는지는 눈에 띄라고 초록색으로 적힙니다. 사진을 디코딩하지 않고 컨테이너에서 읽어 내므로 비용이 들지 않고 곧바로 나타납니다.
3. **형식을 고르고, 세부 정보를 어떻게 할지 정합니다.** 특별한 이유가 없다면 JPEG입니다. 어디서나 열리는 형식이고, 변환하는 목적도 바로 그것이니까요. 화질 슬라이더는 92에 놓여 있는데, 사진을 원본과 구별하기 어려운 설정입니다. 체크박스는 날짜와 카메라, 위치가 함께 갈지를 정합니다.
4. **"변환"을 누르고 내려받습니다.** 디코더는 첫 변환 때 1.4 MB쯤 도착하고, 그것도 딱 한 번뿐입니다. 그 뒤로는 모든 사진이 내 기기에서 디코딩되고 쓰입니다. 파일이 하나면 내려받기 버튼이, 여러 개면 zip도 함께 나옵니다.
## 자세한 설명
[휴대폰이 저장한 사진, 그리고 아무것도 열지 못하는 형식](https://abox.tools/ko/가이드/heic-jpg-변환하기/): 아이폰은 사진을 HEIC로 저장하는데, 인터넷의 절반은 그것을 열지 못합니다. 이 형식이 무엇인지, 왜 Safari만 디코딩하는지, 변환이 사진에서 무엇을 앗아 가는지, 그리고 사진을 누구에게도 업로드하지 않고 변환하는 방법.
## 상자 속 다른 도구
- [증명사진 만들기](https://abox.tools/ko/증명사진-만들기/): 나라를 고르세요. 그 나라의 규정을 그대로 적용합니다.
- [이미지 스택](https://abox.tools/ko/이미지-스택/): 스무 장을 한 장으로. 스무 번의 업로드도, RAW 변환기도 없이.
- [이미지 가리기](https://abox.tools/ko/이미지-가리기/): 가린 부분은 파일에서 지워집니다. 파일 안에 숨겨 두는 것이 아닙니다.
- [EXIF 확인 및 제거](https://abox.tools/ko/exif-정보-삭제/): 사진이 나에 대해 뭘 흘리고 있는지 확인하고, 빼냅니다.
## 자주 묻는 질문
### 제 사진이 어딘가로 업로드되나요?
아닙니다. 파일을 읽고 디코딩하고 쓰는 일은 내 기기에서 도는 내 브라우저가 합니다. 이 도구에는 네트워크 기능이 하나도 없어서 무언가를 가져오지도, 보내지도 않습니다. 이 페이지의 `Content-Security-Policy`에 연결해도 되는 주소가 전부 적혀 있는데, 그중 이 사이트 것은 하나도 없습니다. 실제로 불려 오는 것은 디코더 하나뿐이고, 그것도 이 사이트에서, 한 번, 내 사진이 관여하기 전에 옵니다.
### 이 페이지는 왜 처음에 1.4 MB를 내려받나요?
HEIC가 브라우저로 열 수 없는 유일한 사진 형식이기 때문입니다. 박스 컨테이너에 담긴 HEVC 프레임이고, 애플 하드웨어의 Safari에만 디코더가 있습니다. Chrome, Firefox, Edge는 그냥 거부합니다. 그래서 HEIC 변환기는 어딘가에서 디코더를 구해야 하는데, 올 곳은 두 군데뿐입니다. 서버 아니면 페이지. 다른 변환기는 전부 서버를 골랐고, 그래서 하나같이 사진을 업로드받아야 합니다. 이 도구는 대신 WebAssembly로 컴파일한 `libheif`를 싣고 다닙니다. 이 사이트에서 제공되고, 첫 방문 이후에는 캐시되며, 사진이 아무 데도 가지 않는 대가는 그것이 전부입니다.
### JPEG에 날짜와 카메라, 위치가 남나요?
원하신다면 남고, 페이지의 체크박스로 정합니다. 켜 두면 EXIF 블록을 HEIC에서 꺼내 휴대폰이 쓴 그대로 JPEG에 써 넣습니다. 그래서 변환한 사진이 변환한 날이 아니라 찍은 날 기준으로 정렬됩니다. HEIC 변환기를 두고 가장 흔히 나오는 불만이 바로 그거니까요. 딱 한 태그만 바뀝니다. 방향 태그를 "똑바로"로 맞추는데, 회전이 이미 픽셀에 적용되어 있어서 뷰어가 한 번 더 적용하면 세로 사진이 전부 옆으로 눕기 때문입니다. 체크박스를 끄면 JPEG에는 사진 말고 아무것도 들어가지 않습니다.
### GPS 좌표를 지워 주나요?
좌표가 있다고 알려 드리고, 그다음은 시키시는 대로 합니다. 무엇을 변환하기 전에 각 사진 줄에 좌표가 들어 있는지가 적히는데, 휴대폰도 그 정도는 해 주지 않습니다. "날짜, 카메라, 설정 유지"를 끄면 나머지와 함께 좌표도 JPEG에서 빠지고, 켜 두면 그대로 옮겨집니다. 태그를 자세히 들여다보거나 이미 JPEG인 사진에서 태그를 지우고 싶다면 [EXIF 확인 및 제거](https://abox.tools/ko/exif-정보-삭제/)가 그 일을 하는 도구이고, 사진을 다시 압축하지 않고 해냅니다.
### 사진이 다시 압축되나요?
됩니다. 그럴 수밖에 없습니다. HEIC와 JPEG는 다른 코덱이라, 사진을 디코딩했다가 다시 인코딩하지 않고는 한쪽에서 다른 쪽으로 갈 방법이 없습니다. 정하실 수 있는 것은 그 대가를 얼마로 할지입니다. 화질 슬라이더의 기본값은 92인데, 사진을 원본과 구별하기가 아주 어려운 값입니다. 손실을 전혀 원하지 않고 파일이 5~10배 커져도 괜찮다면 PNG도 고를 수 있습니다.
### 이름은 .jpg인데 실은 HEIC라면요?
그래도 됩니다. 여기 놓인 파일은 이름이 아니라 첫 바이트로 판별합니다. 이름은 그 파일을 마지막으로 만진 앱이 정한 것일 뿐이고, ".jpg"라는 이름으로 도착한 HEIC야말로 사람들이 이런 도구를 찾게 되는 가장 흔한 경로 가운데 하나입니다. 진짜 JPEG나 PNG인 파일은 자기 자신의 사본으로 변환되는 대신 그렇다는 메시지와 함께 거부됩니다.
### 라이브 포토나 연사도 변환되나요?
그 안의 정지 사진은 됩니다. HEIC 하나에 사진이 여러 장 들어갈 수 있는데, 들어 있는 것을 전부 변환하고 원본 이름 뒤에 번호를 붙여 이름 짓습니다. 라이브 포토의 영상 쪽은 휴대폰이 HEIC 옆에 따로 두는 별개의 파일이라, 여기 변환할 대상으로 들어오지 않습니다. 깊이 맵과 미리보기는 컨테이너 안에 있지만 누가 달라고 한 사진이 아니므로 그대로 둡니다.
### 제 AVIF는 왜 안 받나요?
할 일이 없기 때문입니다. AVIF는 HEIC와 같은 컨테이너에 HEVC 대신 AV1이 들어간 것이고, 요즘 브라우저는 전부 그걸 자체적으로 디코딩합니다. 그러니 변환기가 있지도 않은 문제를 풀겠다고 1메가바이트짜리 엔진을 싣고 다니는 셈이 됩니다. AVIF를 JPEG로 만들어야 한다면 [이미지 압축](https://abox.tools/ko/이미지-압축/)과 [이미지 크기 조절](https://abox.tools/ko/이미지-크기-조절/)이 둘 다 브라우저가 이미 가진 디코더로 AVIF를 읽고 JPEG로 씁니다.
### 무료인가요? 가입해야 하나요?
무료이고 계정도, 로그인도, 체험판도, 워터마크도 없습니다. 파일 개수나 용량 제한도 없습니다. 그 값을 치를 서버가 없으니까요. 작업은 내 기기에서 일어납니다. 이 사이트는 광고로 유지되는데, 그 광고에도 내 사진에 관한 것은 넘어가지 않습니다.
### 오프라인에서도 되나요?
됩니다. 디코더까지 포함해서요. 페이지를 한 번 불러온 다음 인터넷을 끊어도 사진 작업이 이전과 똑같이 이어집니다. 아무것도 업로드되지 않는다는 가장 강력한 증명이기도 합니다. HEIC를 어딘가로 보내서 디코딩하는 변환기라면 선을 뽑는 순간 멈출 텐데, 이건 멈추지 않으니까요.
## 이 약속을 직접 확인하는 방법
- **사진은 나갈 곳이 없습니다.** 이 페이지가 연결해도 되는 주소는 Content-Security-Policy에 모두 적혀 있는데, 그중 이 사이트 것은 하나도 없습니다. 파일이 모일 만한 수신 지점이 없고, 설령 있더라도 거기로 파일을 보낼 코드가 없습니다.
- **디코더는 여기서 왔고, 어디로도 가지 않습니다.** HEIC는 박스 형식에 담긴 HEVC이고 Safari 말고는 어떤 브라우저도 디코딩하지 못합니다. 그래서 이 페이지가 WebAssembly로 컴파일한 `libheif`를 싣고 옵니다. 1.4 MB쯤 되고, 이 저장소에 커밋되어 있고, 이 출처에서 제공되며, 여기 다른 파일들과 똑같이 서비스 워커가 캐시합니다. CDN에서 가져오지 않습니다. 그러면 모든 방문 경로에 제삼자가 끼어들고 오프라인 동작도 멈추니까요. 바이너리를 스크립트 옆이 아니라 안에 넣어 둔 것도 정확히 같은 이유입니다. 시작하는 데 요청이 필요 없도록요.
- **여기서는 아무것도 가져오지 않습니다.** 이 도구를 위해 쓴 파일 어디에도 `fetch`도, `XMLHttpRequest`도, `sendBeacon`도 없습니다. 싣고 온 엔진에는 모든 Emscripten 빌드가 그렇듯 `.wasm`을 주소에서 가져오는 로더 경로가 들어 있지만, 그 길로는 가지 않습니다. 바이너리를 이미 손에 쥐고 있으니까요. 설령 간다 해도 `connect-src`에는 구글의 측정 엔드포인트 말고 아무것도 적혀 있지 않아 브라우저가 거부합니다. 증거는 약속이 아니라 정책입니다.
- **메타데이터는 여기서 읽어 화면에 보여 드립니다.** 페이지의 목록이 각 사진에 무엇이 담겨 있는지 말해 줍니다. 날짜, 카메라, 그리고 GPS 좌표가 들어 있는지까지요. JPEG를 누군가에게 건네기 전에 알고 싶은 것들이니까요. 그걸 파일에서 읽는 것은 이 브라우저 안의 `src/boxes.js`이고, 결과는 이 페이지에 표시되며, JPEG에 쓸지 뺄지는 전적으로 고르시기 나름입니다. 이 저장소에는 파일 이름이나 날짜, 좌표, 개수를 실어 보내는 분석 이벤트가 하나도 없습니다.
- **구글이 불러오는 것과, 구글에게 주지 않는 것.** 광고와 측정 스크립트는 구글에서, 후원 버튼은 Buy Me a Coffee에서 옵니다. 어느 쪽에도 내 사진에 관한 것은 넘어가지 않습니다. 파일을 읽고 디코딩하고 쓰는 코드는 한 줄도 빠짐없이 이 출처에서 제공되고 저장소에 공개되어 있습니다.
- **오프라인에서도 동작합니다.** 페이지를 한 번 불러온 뒤 네트워크를 끊어도 도구는 그대로입니다. 디코더도 함께 캐시되어 있으니까요. 가장 간단한 증거이고, 이 사이트의 다른 어디보다 여기서 더 강한 증거입니다. 사진을 어딘가로 보내서 디코딩하는 변환기라면 결코 해낼 수 없는 일이니까요.
**직접 확인해 보세요.** 위에 적은 어느 것도 그냥 믿으실 필요는 없습니다. 이 페이지는 저장소 안의 템플릿과 설정을 빌드 스크립트가 찍어 낸 결과이고, 그 스크립트는 누구나 읽고 직접 돌려 볼 수 있습니다. 결과물은 `dist` 브랜치에 그대로 올라가 있고요. 그래서 실제로 제공되는 파일과 소스를 빌드한 결과를 나란히 놓고 비교해 보실 수 있습니다: https://github.com/A-Box-of-Tools/website
먼저 읽어 볼 파일을 꼽자면, Content-Security-Policy는 `config/site.toml`, 디코더를 어떻게 불러오고 무엇까지 허용하는지는 `src/heif.js`, 사진의 메타데이터를 찾아내는 컨테이너 해석은 `src/boxes.js`, 그 메타데이터가 JPEG로 들어가는 길에 겪는 일은 `src/exif.js`에 있습니다. 엔진 자체는 손대지 않은 `vendor/libheif.js`이고, 라이선스가 그 옆에 있습니다.
HEIC 사진을 JPG로 바꾸는 방법
HEIC 사진을 고릅니다. 휴대폰 백업이든 바탕화면 폴더든, 선택 영역에 끌어다 놓거나 직접 골라 주세요. 브라우저가 디스크에서 읽고, 그동안 어디로도 아무것도 나가지 않습니다. 목록에 각 파일이 무엇이고 안에 무엇이 들었는지가 적힙니다.
사진이 무엇을 담고 있는지 확인합니다. 각 줄에 촬영 날짜와 카메라가 적히고, 그 파일에 GPS 좌표가 들어 있는지는 눈에 띄라고 초록색으로 적힙니다. 사진을 디코딩하지 않고 컨테이너에서 읽어 내므로 비용이 들지 않고 곧바로 나타납니다.
형식을 고르고, 세부 정보를 어떻게 할지 정합니다. 특별한 이유가 없다면 JPEG입니다. 어디서나 열리는 형식이고, 변환하는 목적도 바로 그것이니까요. 화질 슬라이더는 92에 놓여 있는데, 사진을 원본과 구별하기 어려운 설정입니다. 체크박스는 날짜와 카메라, 위치가 함께 갈지를 정합니다.
"변환"을 누르고 내려받습니다. 디코더는 첫 변환 때 1.4 MB쯤 도착하고, 그것도 딱 한 번뿐입니다. 그 뒤로는 모든 사진이 내 기기에서 디코딩되고 쓰입니다. 파일이 하나면 내려받기 버튼이, 여러 개면 zip도 함께 나옵니다.
자세한 설명
휴대폰이 저장한 사진, 그리고 아무것도 열지 못하는 형식아이폰은 사진을 HEIC로 저장하는데, 인터넷의 절반은 그것을 열지 못합니다. 이 형식이 무엇인지, 왜 Safari만 디코딩하는지, 변환이 사진에서 무엇을 앗아 가는지, 그리고 사진을 누구에게도 업로드하지 않고 변환하는 방법.
아닙니다. 파일을 읽고 디코딩하고 쓰는 일은 내 기기에서 도는 내 브라우저가 합니다. 이 도구에는 네트워크 기능이 하나도 없어서 무언가를 가져오지도, 보내지도 않습니다. 이 페이지의 Content-Security-Policy에 연결해도 되는 주소가 전부 적혀 있는데, 그중 이 사이트 것은 하나도 없습니다. 실제로 불려 오는 것은 디코더 하나뿐이고, 그것도 이 사이트에서, 한 번, 내 사진이 관여하기 전에 옵니다.
이 페이지는 왜 처음에 1.4 MB를 내려받나요?
HEIC가 브라우저로 열 수 없는 유일한 사진 형식이기 때문입니다. 박스 컨테이너에 담긴 HEVC 프레임이고, 애플 하드웨어의 Safari에만 디코더가 있습니다. Chrome, Firefox, Edge는 그냥 거부합니다. 그래서 HEIC 변환기는 어딘가에서 디코더를 구해야 하는데, 올 곳은 두 군데뿐입니다. 서버 아니면 페이지. 다른 변환기는 전부 서버를 골랐고, 그래서 하나같이 사진을 업로드받아야 합니다. 이 도구는 대신 WebAssembly로 컴파일한 libheif를 싣고 다닙니다. 이 사이트에서 제공되고, 첫 방문 이후에는 캐시되며, 사진이 아무 데도 가지 않는 대가는 그것이 전부입니다.
JPEG에 날짜와 카메라, 위치가 남나요?
원하신다면 남고, 페이지의 체크박스로 정합니다. 켜 두면 EXIF 블록을 HEIC에서 꺼내 휴대폰이 쓴 그대로 JPEG에 써 넣습니다. 그래서 변환한 사진이 변환한 날이 아니라 찍은 날 기준으로 정렬됩니다. HEIC 변환기를 두고 가장 흔히 나오는 불만이 바로 그거니까요. 딱 한 태그만 바뀝니다. 방향 태그를 "똑바로"로 맞추는데, 회전이 이미 픽셀에 적용되어 있어서 뷰어가 한 번 더 적용하면 세로 사진이 전부 옆으로 눕기 때문입니다. 체크박스를 끄면 JPEG에는 사진 말고 아무것도 들어가지 않습니다.
GPS 좌표를 지워 주나요?
좌표가 있다고 알려 드리고, 그다음은 시키시는 대로 합니다. 무엇을 변환하기 전에 각 사진 줄에 좌표가 들어 있는지가 적히는데, 휴대폰도 그 정도는 해 주지 않습니다. "날짜, 카메라, 설정 유지"를 끄면 나머지와 함께 좌표도 JPEG에서 빠지고, 켜 두면 그대로 옮겨집니다. 태그를 자세히 들여다보거나 이미 JPEG인 사진에서 태그를 지우고 싶다면 EXIF 확인 및 제거가 그 일을 하는 도구이고, 사진을 다시 압축하지 않고 해냅니다.
사진이 다시 압축되나요?
됩니다. 그럴 수밖에 없습니다. HEIC와 JPEG는 다른 코덱이라, 사진을 디코딩했다가 다시 인코딩하지 않고는 한쪽에서 다른 쪽으로 갈 방법이 없습니다. 정하실 수 있는 것은 그 대가를 얼마로 할지입니다. 화질 슬라이더의 기본값은 92인데, 사진을 원본과 구별하기가 아주 어려운 값입니다. 손실을 전혀 원하지 않고 파일이 5~10배 커져도 괜찮다면 PNG도 고를 수 있습니다.
이름은 .jpg인데 실은 HEIC라면요?
그래도 됩니다. 여기 놓인 파일은 이름이 아니라 첫 바이트로 판별합니다. 이름은 그 파일을 마지막으로 만진 앱이 정한 것일 뿐이고, ".jpg"라는 이름으로 도착한 HEIC야말로 사람들이 이런 도구를 찾게 되는 가장 흔한 경로 가운데 하나입니다. 진짜 JPEG나 PNG인 파일은 자기 자신의 사본으로 변환되는 대신 그렇다는 메시지와 함께 거부됩니다.
라이브 포토나 연사도 변환되나요?
그 안의 정지 사진은 됩니다. HEIC 하나에 사진이 여러 장 들어갈 수 있는데, 들어 있는 것을 전부 변환하고 원본 이름 뒤에 번호를 붙여 이름 짓습니다. 라이브 포토의 영상 쪽은 휴대폰이 HEIC 옆에 따로 두는 별개의 파일이라, 여기 변환할 대상으로 들어오지 않습니다. 깊이 맵과 미리보기는 컨테이너 안에 있지만 누가 달라고 한 사진이 아니므로 그대로 둡니다.
제 AVIF는 왜 안 받나요?
할 일이 없기 때문입니다. AVIF는 HEIC와 같은 컨테이너에 HEVC 대신 AV1이 들어간 것이고, 요즘 브라우저는 전부 그걸 자체적으로 디코딩합니다. 그러니 변환기가 있지도 않은 문제를 풀겠다고 1메가바이트짜리 엔진을 싣고 다니는 셈이 됩니다. AVIF를 JPEG로 만들어야 한다면 이미지 압축과 이미지 크기 조절이 둘 다 브라우저가 이미 가진 디코더로 AVIF를 읽고 JPEG로 씁니다.
무료인가요? 가입해야 하나요?
무료이고 계정도, 로그인도, 체험판도, 워터마크도 없습니다. 파일 개수나 용량 제한도 없습니다. 그 값을 치를 서버가 없으니까요. 작업은 내 기기에서 일어납니다. 이 사이트는 광고로 유지되는데, 그 광고에도 내 사진에 관한 것은 넘어가지 않습니다.
오프라인에서도 되나요?
됩니다. 디코더까지 포함해서요. 페이지를 한 번 불러온 다음 인터넷을 끊어도 사진 작업이 이전과 똑같이 이어집니다. 아무것도 업로드되지 않는다는 가장 강력한 증명이기도 합니다. HEIC를 어딘가로 보내서 디코딩하는 변환기라면 선을 뽑는 순간 멈출 텐데, 이건 멈추지 않으니까요.