Base64를 이미지로 변환하는 방법
- 입력란에 문자열을 붙여넣으세요. 파일에 저장된 긴 값은 .txt 파일 열기로 열거나 입력란에 놓으면 됩니다.
- 실시간이 켜져 있으면 붙여넣는 즉시 이미지가 디코딩됩니다. 상태 표시줄에 Base64가 올바른지, 변형(표준 또는 Base64URL), 바이트 수, 감지된 형식이 나옵니다.
- 미리보기를 확인하세요. 그 아래에 형식, MIME 유형, 확장자, 바이트 크기, 픽셀 크기, SHA-256 해시가 표시됩니다.
- 원하면 파일 이름을 바꾸고 파일 다운로드를 누르세요. HTML이나 CSS에 쓸 깔끔한
data:URI가 필요하면 대신 data URI로 복사를 누르세요.
예시는 작은 PNG를 불러오므로, 직접 데이터를 붙여넣기 전에 결과가 어떻게 보이는지 확인할 수 있습니다.
붙여넣을 수 있는 것
이미지 문자열이 깔끔한 상태로 오는 일은 드물기 때문에, 디코더는 Base64를 감싼 부분에 관대합니다.
- 순수 Base64, API가 돌려주는 그대로:
iVBORw0KGgoAAAANSUhEUg... - data URI:
data:image/png;base64,iVBORw0KGgo... - data URI가 들어 있는 코드:
background-image: url("data:image/svg+xml;base64,..."),<img src="data:image/jpeg;base64,...">, Markdown 이미지, 값이 data URI인 JSON 필드. 첫 번째 data URI를 자동으로 추출합니다. - 줄 바꿈된 Base64: 이메일 소스나 PEM 형식 출력처럼 64자나 76자마다 공백이나 줄 바꿈이 있는 경우.
- URL-safe Base64:
-와_를 쓰는 문자열,=패딩이 없는 문자열, 따옴표로 감싼 값.
Base64가 data: 접두사 없이 JSON 필드에 들어 있다면 따옴표 사이의 값만 복사하세요. JSON 문서 전체는 {가 알파벳에 없으므로 올바르지 않은 Base64로 거부됩니다.
형식을 감지하는 방식
모든 이미지 형식은 매직 바이트라는 고정된 시그니처로 시작합니다. 도구는 문자열을 디코딩해 첫 바이트를 이 시그니처들과 비교하므로, image/png라고 적혀 있지만 실제로는 JPEG인 문자열도 JPEG로 인식합니다. 같은 시그니처는 Base64 자체에서도 보이므로 로그나 데이터베이스 덤프를 읽을 때 도움이 됩니다.
| 형식 | 첫 바이트 | Base64 시작 부분 | MIME 유형 |
|---|---|---|---|
| PNG | 89 50 4E 47 0D 0A 1A 0A | iVBORw0KGgo | image/png |
| JPEG | FF D8 FF | /9j/ | image/jpeg |
| GIF | GIF89a / GIF87a | R0lGODlh / R0lGODdh | image/gif |
| WebP | RIFF, 크기, WEBP | UklGR, 12–16번째 글자에 XRUJQ | image/webp |
| SVG | <svg / <?xml | PHN2Zy / PD94bWwg | image/svg+xml |
| ICO | 00 00 01 00 | AAABAA | image/x-icon |
| BMP | BM | Qk | image/bmp |
| HEIC | 크기, ftypheic | AAAA, 9번째 글자부터 eXBoZWlj | image/heic |
| TIFF | II* / MM* | SUkqAA / TU0AKg | image/tiff |
AVIF, JPEG XL, 커서(.cur) 파일도 감지합니다. data URI가 선언한 형식과 내용이 다르면 안내에 둘 다 표시됩니다. PDF처럼 데이터가 아예 이미지가 아니라면 페이지가 그 사실을 알리고 .pdf(으)로 다운로드 버튼을 보여 줍니다. 더 많은 파일 형식의 시그니처는 자주 보는 Base64 접두사 페이지에 있습니다.
이미지가 보이지 않는 이유
문자열이 잘렸습니다. Base64 값은 로그 한 줄 길이 제한, 데이터베이스 열 크기, 스프레드시트 셀(32,767자), 터미널 복사 때문에 잘리곤 합니다. 그러면 JPEG나 PNG가 일부만 렌더링되거나 미리보기가 실패합니다. 글자가 하나 많거나 적어서 길이가 불가능해지면 “길이가 잘못되었습니다” 오류가 납니다. 올바르지만 짧은 문자열은 오류 없이 디코딩되므로, 크기를 예상한 값과 비교하세요.
data URI의 MIME 유형이 틀렸습니다. JPEG 바이트 앞에 data:image/png가 붙어 있어도 래스터 이미지를 추측해 읽는 브라우저에서는 대개 표시되지만, 다른 소프트웨어는 레이블을 믿습니다. SVG는 절대 추측하지 않으므로 image/svg+xml이 아닌 유형이 붙어 있으면 <img>에서 렌더링되지 않습니다. 도구는 미리보기와 다운로드에 실제 형식을 사용합니다.
전송 중에 문자가 바뀌었습니다. 폼 인코딩을 거친 +는 공백으로 돌아오는 경우가 많습니다. 한 줄짜리 문자열에 공백이 있고 +가 하나도 없으면 디코더가 공백을 +로 되돌립니다. 둘 다 있으면 구별할 수 없어 이미지가 엉뚱한 바이트로 디코딩될 수 있습니다. 일부 라이브러리가 쓴 JSON은 슬래시를 \/로 이스케이프하는데, 디코더가 이런 이스케이프와 리터럴 \n 시퀀스를 제거해 줍니다. 더 복잡한 경우에는 Base64 복구가 수정한 내용을 모두 보여 줍니다.
두 번 인코딩되었습니다. 디코딩된 바이트 자체가 Base64 텍스트라면 안내가 나오고, 다시 디코딩으로 다음 층을 풀 수 있습니다. 뒤로는 이전 단계로 돌아갑니다. Base64 안의 data URI나 gzip, zlib로 압축된 데이터도 같은 방식으로 처리됩니다.
브라우저가 그 형식을 표시하지 못합니다. iPhone의 HEIC 사진은 Safari 17 이상에서만, TIFF는 Safari에서만 표시되며, JPEG XL은 Safari 17, Chrome 155, Firefox 158 이상이 필요합니다. 이때 미리보기는 브라우저가 표시할 수 없다고 알리지만 바이트는 온전합니다. 파일 다운로드로 사진 앱에서 열 수 있는 정상 파일을 저장할 수 있습니다.
이미지가 아닙니다. JVBER로 시작하는 Base64 문자열은 PDF이고, UEsDB는 ZIP 압축 파일입니다. 문서, 압축 파일, 오디오 등을 미리 보여 주는 Base64를 파일로를 사용하세요.
올바른 확장자로 저장하기
확장자와 MIME 유형 필드는 직접 수정하기 전까지 감지된 형식으로 채워지므로, 입력 어디에도 “PNG"라는 말이 없어도 PNG는 .png로 저장됩니다. Windows와 업로드 폼은 파일을 확장자로 판단합니다. WebP의 이름을 .jpg로 바꿔도 안은 여전히 WebP이며, 엄격한 소프트웨어는 이를 거부합니다.
두 필드 모두 직접 바꿀 수 있습니다. 예를 들어 아이콘을 .cur로 저장하거나 원하는 MIME 유형을 입력할 수 있습니다. MIME 유형을 바꾸면 미리보기도 그 유형으로 다시 렌더링됩니다.
SHA-256과 hex 덤프
미리보기 아래의 SHA-256 해시는 디코딩된 바이트로 계산합니다. 보낸 사람이 준 해시, 데이터베이스 레코드, sha256sum image.png 결과와 비교하면 저장한 그림이 인코딩된 파일과 바이트 하나까지 똑같다는 것을 증명할 수 있습니다. 다른 데이터의 해시는 SHA-256 도구를 참고하세요.
hex 덤프 표시는 처음 512바이트를 보여 줍니다. 오프셋 0x10의 PNG 너비와 높이, 카메라 JPEG의 Exif 마커, ICO 파일의 이미지 디렉터리처럼 헤더를 살펴보는 가장 빠른 방법입니다.
개인정보: 이미지는 기기에 남습니다
Base64 이미지는 아무 웹사이트에나 올리고 싶지 않은 것인 경우가 많습니다. 버그 리포트의 스크린샷, 신분증이나 여권 스캔본, 환자 포털에서 내보낸 의료 영상, 태블릿으로 받은 서명 같은 것들입니다. 이 페이지는 이런 이미지를 전부 브라우저 안에서 디코딩합니다. 페이지의 Content Security Policy가 Cloudflare 조회수 집계를 제외한 스크립트의 네트워크 요청을 차단하고, 파일 다운로드는 로컬 blob: URL에서 저장합니다. 붙여넣은 내용은 사이트에 저장되지 않습니다.
코드에서 Base64 이미지 디코딩하기
Python에서는 접두사를 제거하고 패딩을 복원한 뒤 시그니처로 확장자를 고릅니다.
import base64, re
def save_image(b64: str, stem: str = "image") -> str:
b64 = re.sub(r"^data:[^,]*;base64,", "", b64.strip(), flags=re.I)
b64 = re.sub(r"\s+", "", b64).replace("-", "+").replace("_", "/")
data = base64.b64decode(b64 + "=" * (-len(b64) % 4))
if data.startswith(b"\x89PNG"):
ext = "png"
elif data.startswith(b"\xff\xd8\xff"):
ext = "jpg"
elif data.startswith(b"GIF8"):
ext = "gif"
elif data[:4] == b"RIFF" and data[8:12] == b"WEBP":
ext = "webp"
else:
ext = "bin"
with open(f"{stem}.{ext}", "wb") as f:
f.write(data)
return f"{stem}.{ext}"
브라우저에서는 문자열을 Blob으로 바꾸고 객체 URL로 보여 줍니다.
function base64ToBlob(b64, type = "image/png") {
const bin = atob(b64.replace(/^data:[^,]*;base64,/, "").replace(/\s+/g, ""));
const bytes = Uint8Array.from(bin, c => c.charCodeAt(0));
return new Blob([bytes], { type });
}
img.src = URL.createObjectURL(base64ToBlob(str));
바이너리 데이터 읽기와 쓰기는 Python에서 Base64와 JavaScript에서 Base64에 더 자세히 있습니다. 반대 방향으로 그림을 인코딩하려면 크기 조정과 형식 변환을 지원하는 이미지를 Base64로를 사용하세요.
자주 묻는 질문
data:image/png;base64, 접두사가 꼭 있어야 하나요?
아닙니다. 순수 Base64도 되며, 형식은 디코딩된 바이트로 판별합니다. data URI 전체를 붙여넣으면 접두사는 자동으로 제거되고, 선언된 형식이 내용과 맞는지 확인합니다.
Base64 문자열이 어떤 이미지 형식인지 어떻게 아나요?
첫 글자들을 보세요. iVBORw0KGgo는 PNG, /9j/는 JPEG, R0lGOD는 GIF, UklGR는 WebP 같은 RIFF 파일입니다. 위에 붙여넣으면 감지된 형식 필드가 형식을 알려 줍니다.
디코딩한 이미지의 아래쪽이 잘려 보이는 이유는 무엇인가요?
복사, 로그 기록, 저장 과정에서 Base64 문자열이 잘렸기 때문입니다. 브라우저는 불완전한 PNG나 JPEG를 그릴 수 있는 만큼만 그립니다. 원본에서 값을 다시 복사하세요. 문자열에 없는 바이트는 어떤 도구로도 복원할 수 없습니다.
스크린샷이나 신분증 사진을 여기서 디코딩해도 안전한가요?
디코딩은 이 페이지의 JavaScript에서 이루어지고, Content Security Policy가 Cloudflare 조회수 집계를 제외한 페이지의 모든 네트워크 요청을 차단하므로 이미지는 어디로도 전송되지 않습니다. 디코딩하는 동안 브라우저 개발자 도구의 네트워크 패널을 보면 직접 확인할 수 있습니다.
디코딩한 이미지를 다른 형식으로 변환할 수 있나요?
아닙니다. 인코딩된 바이트를 그대로 저장합니다. PNG, JPEG, WebP 버전이 필요하다면 파일을 다운로드해 이미지를 Base64로에서 변환 형식을 지정해 인코딩한 다음, 그 결과를 디코딩하세요.