← 블로그 목록
윈도우작성 · 7분 읽기

PNG를 ICO로 변환하는 법 — 윈도우에서 설치 없이 아이콘 파일 만들기 (흔한 방법이 16색으로 깨지는 이유)

프로그램이나 바로가기에 쓸 아이콘을 만들려면 PNG 를 ICO 로 바꿔야 합니다. 검색하면 변환 사이트가 대부분인데, 윈도우에 이미 있는 PowerShell 로도 설치 없이 만들 수 있습니다. 다만 흔히 퍼진 한 줄짜리 방법은 색이 16색으로 줄거나 파일이 깨지고, 이름만 .ico 로 바꾼 파일은 윈도우가 아예 열지 못했습니다. 같은 로고 PNG 로 방법마다 직접 만들어 윈도우가 실제로 여는지, 색과 투명이 남는지 재 본 결과를 정리했습니다.

이미지 변환기 — 실제 실행 화면
실제 실행 화면
이 글에서 소개하는 무료 도구
이미지 변환기

원본이 JPG·WebP 라면 먼저 투명 배경 PNG 로 바꿔 두세요. '배경 지우기'(스포이드)로 단색 배경을 투명하게 만들 수 있고, 파일은 브라우저 안에서만 처리됩니다. ICO 저장 기능은 없습니다.

  • ✓ 무료
  • ✓ 설치·회원가입 없음
  • ✓ 브라우저에서 바로 실행
  • ✓ 파일이 서버로 올라가지 않음
  • ✓ 소스 공개

🔒 파일을 서버나 다른 어떤 곳으로도 보내지 않습니다 — 내 컴퓨터의 브라우저 안에서만 처리합니다.

이동할 주소 — 지금 보고 있는 이 사이트(coding-now.com) 안의 페이지입니다
🔒 https://www.coding-now.com/image-converter

ICO 는 PNG 와 무엇이 다른가

ICO 는 그림 한 장이 아니라 여러 크기의 그림을 담는 상자입니다. 파일 맨 앞 6바이트가 머리글(00 00 01 00 + 그림 개수)이고, 그 뒤에 그림마다 16바이트짜리 목록(가로·세로·색 깊이·데이터 크기·위치)이 붙고, 마지막에 실제 그림 데이터가 이어집니다. 윈도우는 화면 배율과 쓰이는 곳(제목 표시줄·작업 표시줄·시작 메뉴)에 맞는 크기를 골라 씁니다.

마이크로소프트 'Construct your Windows App's Icon' 문서는 앱 아이콘에 최소 16×16, 24×24, 32×32, 48×48, 256×256 을 넣으라고 하고, 정확히 맞는 크기가 없으면 다음으로 큰 크기를 줄여 쓴다고 설명합니다. 256 을 넣어 두면 윈도우가 늘리지 않고 줄이기만 한다는 뜻입니다. 윈도우 비스타부터는 그림 데이터로 BMP 대신 PNG 를 그대로 담을 수 있어서, 256×256 같은 큰 크기도 투명도(32비트)를 살린 채 작게 넣을 수 있습니다.

목록의 가로·세로 칸은 1바이트라 256 은 0 으로 적습니다. 그래서 ICO 한 장에 넣을 수 있는 가장 큰 크기는 256×256 입니다.

이름만 .ico 로 바꾸면 왜 안 되나

PNG 파일은 89 50 4E 47(‰PNG) 로 시작합니다. 이름만 logo.ico 로 바꿔도 내용은 그대로 PNG 라 ICO 머리글이 없습니다. 이 PC 에서 윈도우가 .ico 파일을 아이콘으로 읽을 때 쓰는 API(LoadImage)로 열어 보니 16·32·48·256 모두 실패했고, .NET 의 Icon 클래스도 “Argument 'picture' must be a picture that can be used as a Icon.” 오류를 냈습니다.

가지고 있는 .ico 가 진짜 ICO 인지는 첫 4바이트로 바로 알 수 있습니다. PowerShell 창에 붙여 넣고 경로만 바꾸세요.

powershell
$b = [IO.File]::ReadAllBytes("C:\Users\you\Pictures\logo.ico")
"{0:X2} {1:X2} {2:X2} {3:X2}  images: {4}" -f $b[0], $b[1], $b[2], $b[3], $b[4]

진짜 ICO 는 00 00 01 00 과 그림 개수(아래 스크립트로 만든 파일은 images: 5)가 나오고, 이름만 바꾼 PNG 는 89 50 4E 47 이 나옵니다(이때 뒤의 숫자는 의미 없음).

방법 1. PowerShell — 설치 없이 PNG 를 ICO 로 (추천)

윈도우 10·11 에 들어 있는 Windows PowerShell 과 .NET 그림 기능만 씁니다. 원본 PNG 를 다섯 크기(16·24·32·48·256)로 줄여 각각 PNG 로 만든 뒤, ICO 머리글과 목록을 직접 적어 한 파일로 묶습니다.

powershell
Add-Type -AssemblyName System.Drawing
$src = "C:\Users\you\Pictures\logo.png"   # the PNG to convert (full path)
$out = "C:\Users\you\Pictures\logo.ico"   # the icon to create (full path)
$sizes = 16, 24, 32, 48, 256

$img = [System.Drawing.Image]::FromFile($src)
$pngs = foreach ($n in $sizes) {
  $b = New-Object System.Drawing.Bitmap $n, $n
  $g = [System.Drawing.Graphics]::FromImage($b)
  $g.InterpolationMode = "HighQualityBicubic"
  $k = $n / [Math]::Max($img.Width, $img.Height)        # keep the aspect ratio
  $w = $img.Width * $k; $h = $img.Height * $k
  $g.DrawImage($img, ($n - $w) / 2, ($n - $h) / 2, $w, $h); $g.Dispose()
  $ms = New-Object IO.MemoryStream
  $b.Save($ms, [System.Drawing.Imaging.ImageFormat]::Png); $b.Dispose()
  , $ms.ToArray()
}
$img.Dispose()

$bw = New-Object IO.BinaryWriter([IO.File]::Create($out))
$bw.Write([UInt16]0); $bw.Write([UInt16]1); $bw.Write([UInt16]$sizes.Count)
$offset = 6 + 16 * $sizes.Count
for ($i = 0; $i -lt $sizes.Count; $i++) {
  $n = $sizes[$i] % 256                                  # 256 is stored as 0
  $bw.Write([byte]$n); $bw.Write([byte]$n); $bw.Write([byte]0); $bw.Write([byte]0)
  $bw.Write([UInt16]1); $bw.Write([UInt16]32)
  $bw.Write([UInt32]$pngs[$i].Length); $bw.Write([UInt32]$offset)
  $offset += $pngs[$i].Length
}
foreach ($p in $pngs) { $bw.Write($p) }
$bw.Close()
  1. 1시작 메뉴에서 Windows PowerShell 을 엽니다(관리자 권한 필요 없음).
  2. 2위 코드에서 $src·$out 두 줄의 경로를 내 파일로 바꿉니다. 전체 경로로 적으세요 — .NET 함수는 PowerShell 의 현재 폴더가 아니라 프로세스 기준 폴더에 파일을 쓸 수 있습니다.
  3. 3전체를 복사해 PowerShell 창에 붙여 넣고 Enter. 아무 메시지 없이 끝나면 $out 경로에 .ico 가 생깁니다.
  4. 4위의 머리글 확인 코드로 00 00 01 00 · images: 5 가 나오는지 봅니다.

이 PC 에서 512×512 투명 배경 로고로 만든 결과는 10,899바이트, 안에 16·24·32·48·256 다섯 장이 모두 32비트 PNG 로 들어갔고, LoadImage 로 16·32·48·256 모두 열렸습니다. 원 안쪽 색 (37, 99, 235)도 원본과 같았습니다.

원본이 정사각형이 아니어도 됩니다. 스크립트가 가로·세로 비율을 지키며 가운데에 놓고 남는 곳을 투명하게 채웁니다. 300×200 PNG 로 시험하니 다섯 장 모두 정사각형으로 나오고 위아래가 투명했습니다.

⚠️

코드를 .ps1 파일로 저장해 실행한다면, 한글을 넣은 채 BOM 없는 UTF-8 로 저장하지 마세요. 이 글을 쓰며 시험할 때 Windows PowerShell 5.1 이 그런 파일을 한국어 코드 페이지로 읽어 한글 주석 다음 줄이 실행되지 않았습니다(오류 없이 크기 목록이 비어 6바이트짜리 파일이 나옴). 위 코드는 주석까지 영어라 그대로 붙여 넣으면 문제없습니다.

흔히 퍼진 PowerShell 한 줄이 16색으로 깨지는 이유

'PowerShell png to ico' 로 찾으면 가장 많이 보이는 코드가 이것입니다. 짧아서 편해 보이지만 결과가 좋지 않았습니다.

powershell
Add-Type -AssemblyName System.Drawing
$bmp = New-Object System.Drawing.Bitmap "C:\Users\you\Pictures\logo.png"
$icon = [System.Drawing.Icon]::FromHandle($bmp.GetHicon())
$fs = [IO.File]::Create("C:\Users\you\Pictures\logo.ico"); $icon.Save($fs); $fs.Close()

512×512 원본에 그대로 쓰니 파일은 32,894바이트로 만들어졌지만, 목록에는 그림 데이터가 163,944바이트라고 적혀 있어 내용이 잘린 파일이었습니다. LoadImage 는 16·32·48·256 모두 실패, 파이썬 Pillow 도 'not enough image data' 로 열지 못했습니다.

원본을 256×256 으로 줄인 뒤 같은 방법을 쓰면 41,086바이트 파일이 생기고 윈도우도 엽니다. 그런데 안을 보면 4비트(16색) BMP 한 장뿐입니다. 원 안쪽 파랑 (37, 99, 235)은 (0, 0, 255)로 바뀌었고, 가장자리의 반투명 칸은 0개가 됐습니다. 왜 이렇게 저장되는지는 .NET 내부 동작이라 확인하지 못했고, 결과만 재 본 것입니다.

같은 점의 색 — 원본·GetHicon ICO·PNG 를 담은 ICO (256×256, 이 PC 실측)

파일 크기도 가장 큽니다. 같은 로고로 세 방법을 비교하면 이렇습니다.

같은 로고를 세 방법으로 ICO 로 만든 크기 (이 PC 실측)

방법 2. 파이썬 Pillow — 세 줄로

파이썬이 있다면 이미지 라이브러리 Pillow 로 간단히 됩니다(pip install pillow). 이 PC 는 Python 3.11.9 · Pillow 12.3.0 입니다.

python
from PIL import Image          # pip install pillow
img = Image.open("logo.png")
img.save("logo.ico", sizes=[(16, 16), (24, 24), (32, 32), (48, 48), (256, 256)])

크기 다섯 개를 지정한 결과는 14,376바이트, 다섯 장 모두 PNG 로 들어갔고 색과 반투명 가장자리(2,212칸)가 원본과 같았습니다. sizes 를 빼면 Pillow 가 16·24·32·48·64·128·256 일곱 장을 넣어 21,644바이트가 됩니다.

  • 원본보다 큰 크기는 빠집니다. 100×100 원본으로 저장하니 16·24·32·48·64 다섯 장만 들어가고 128·256 은 없었습니다. 큰 아이콘 자리에 맞는 그림이 빠지는 셈입니다.
  • 정사각형이 아니면 직사각형 아이콘이 됩니다. 300×200 원본은 16×11, 24×16, 32×21 … 128×85 로 저장됐습니다. 정사각형이 필요하면 PowerShell 스크립트처럼 투명 여백을 먼저 붙이세요.

방법별 비교

방법설치결과(512 로고)윈도우가 열기색 · 투명
이름만 .ico 로 바꾸기없음PNG 그대로 19,053바이트실패—
흔한 PowerShell 한 줄(GetHicon)없음512 원본: 깨진 파일 · 256 원본: 41,086바이트 한 장512: 실패 · 256: 성공16색, 반투명 사라짐
PowerShell 스크립트(PNG 담기)없음10,899바이트 · 16·24·32·48·256성공그대로(32비트)
파이썬 PillowPython + Pillow14,376바이트(크기 지정) · 기본 21,644바이트성공그대로(32비트)
온라인 변환 사이트없음사이트마다 다름확인 안 함확인 안 함

온라인 변환 사이트는 파일이 그 사이트 서버로 올라갑니다. 공개된 로고라면 상관없지만 회사 내부 자료라면 PC 안에서 끝나는 PowerShell 이나 Pillow 를 권합니다.

아이콘이 이상하게 나올 때 확인할 순서

ICO 가 안 열리거나 이상할 때 — 위에서부터 확인
  1. 1머리글 — 머리글 확인 코드로 00 00 01 00 이 나오는지. 89 50 4E 47 이면 이름만 바뀐 PNG 입니다. 위 방법으로 다시 만드세요.
  2. 2색 깊이 — 색이 원색으로 바뀌고 가장자리가 계단처럼 보이면 GetHicon 방식으로 만든 16색 ICO 일 가능성이 큽니다. PNG 를 담는 방법으로 다시 만드세요.
  3. 3원본 크기 — 100×100 원본을 PowerShell 스크립트로 256 까지 늘리면 가장자리 반투명 칸이 924칸에서 5,923칸으로 늘었습니다(번진다는 뜻). 원본은 256px 이상으로 준비하세요.
  4. 4모양·배경 — 투명 정보가 없는 원본(JPG 등)이면 배경까지 아이콘이 되어 네모로 보입니다. 시험 로고에서 투명 정보를 빼고 저장하니 투명했던 모서리가 검정 (0, 0, 0)이 됐습니다 — 투명한 칸에 숨어 있던 색이 드러난 것입니다. 이미지 변환기의 '배경 지우기'로 PNG 를 먼저 만드세요.

자주 묻는 질문

Q. ICO 안에 크기를 몇 개 넣어야 하나요?

마이크로소프트 문서는 앱 아이콘에 최소 16·24·32·48·256 을 권합니다. 정확한 크기가 없으면 윈도우가 다음으로 큰 크기를 줄여 쓰므로, 256 을 넣어 두면 늘려서 흐려지는 일이 없습니다. 이 글의 PowerShell 스크립트와 Pillow 예시가 이 다섯 크기를 넣습니다.

Q. 512px 나 1024px 아이콘도 만들 수 있나요?

ICO 목록의 가로·세로 칸이 1바이트라 256 이 상한입니다. 512 PNG 를 그대로 담아 봤더니 목록에는 256 으로 적혔고, Pillow 는 열면서 'Image was not the expected size' 경고를 냈습니다. 256 으로 줄여 넣으세요.

Q. PNG 파일 이름만 .ico 로 바꾸면 안 되나요?

안 됐습니다. 이름만 바꾼 PNG 는 윈도우 아이콘 API 가 16·32·48·256 어느 크기로도 열지 못했습니다. ICO 는 머리글과 크기 목록이 따로 있는 형식이라 변환이 필요합니다.

Q. 투명했던 배경이 검게(또는 하얗게) 나와요.

원본에 투명 정보가 없거나, 중간에 JPG 처럼 투명을 지원하지 않는 형식을 거친 경우입니다. 시험 로고에서 투명 정보를 빼니 투명했던 칸이 검정 (0, 0, 0)으로 채워졌습니다. 투명 배경 PNG 로 다시 만든 뒤 변환하세요.

Q. 그림판에서 ICO 로 저장할 수 있나요?

이 글에서는 그림판 저장 형식을 확인하지 않았습니다. 확실한 방법은 위의 PowerShell 스크립트나 Pillow 입니다.

이 글에서 소개하는 무료 도구
이미지 변환기

원본이 JPG·WebP 라면 먼저 투명 배경 PNG 로 바꿔 두세요. '배경 지우기'(스포이드)로 단색 배경을 투명하게 만들 수 있고, 파일은 브라우저 안에서만 처리됩니다. ICO 저장 기능은 없습니다.

  • ✓ 무료
  • ✓ 설치·회원가입 없음
  • ✓ 브라우저에서 바로 실행
  • ✓ 파일이 서버로 올라가지 않음
  • ✓ 소스 공개

🔒 파일을 서버나 다른 어떤 곳으로도 보내지 않습니다 — 내 컴퓨터의 브라우저 안에서만 처리합니다.

이동할 주소 — 지금 보고 있는 이 사이트(coding-now.com) 안의 페이지입니다
🔒 https://www.coding-now.com/image-converter

댓글 0

아직 댓글이 없습니다. 첫 댓글을 남겨 주세요.

댓글은 회원만 쓸 수 있습니다.

광고·욕설·비방·개인정보·불법 내용이 담긴 댓글은 숨기거나 지웁니다. 댓글은 닉네임과 함께 공개됩니다. 개인정보처리방침

다른 글