wxWidgets/misc/scripts/png2c.py
Vadim Zeitlin 46eada874a Add an option to embed image size in its name to PNG-to-C script.
When a PNG image exists in several sizes it makes sense to use its size as a
suffix to distinguish the different versions, so update the png2c script to
optionally allow to do this.

Current implementation simply checks the PNG header directly to avoid any
extra dependencies.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@66502 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2010-12-31 17:38:40 +00:00

90 lines
2.9 KiB
Python
Executable File

#!/usr/bin/python
# This script is a slightly modified version of the original found at
#
# http://wiki.wxwidgets.org/Embedding_PNG_Images-Bin2c_In_Python
#
# without any copyright attribution so it is assumed it can be used under
# wxWindows licence as the rest of the wiki material.
import sys
import os
import os.path
import re
import array
USAGE = """Usage: png2c [-s] [file...]
Output input PNG files as C arrays to standard output. Used to embed PNG images
in C code (like XPM but with full alpha channel support).
-s embed the image size in the image names in generated code."""
if len(sys.argv) < 2:
print USAGE
sys.exit(1)
r = re.compile("^([a-zA-Z._][a-zA-Z._0-9]*)[.][pP][nN][gG]$")
with_size = 0
size_suffix = ''
for path in sys.argv[1:]:
if path == '-s':
with_size = 1
continue
filename = os.path.basename(path).replace('-','_')
m = r.match(filename)
# Allow only filenames that make sense as C variable names
if not(m):
print "Skipped file (unsuitable filename): " + filename
continue
# Read PNG file as character array
bytes = array.array('B', open(path, "rb").read())
count = len(bytes)
# Check that it's actually a PNG to avoid problems when loading it
# later.
#
# Each PNG file starts with a 8 byte signature that should be followed
# by IHDR chunk which is always 13 bytes in length so the first 16
# bytes are fixed (or at least we expect them to be).
if bytes[0:16].tostring() != '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR':
print '"%s" doesn\'t seem to be a valid PNG file.' % filename
continue
# Try to naively get its size if necessary
if with_size:
width = bytes[19] + 16*bytes[18] + 256*bytes[17] + 4096*bytes[16]
height = bytes[23] + 16*bytes[22] + 256*bytes[21] + 4096*bytes[20]
size_suffix = "_%dx%d" % (width, height)
# Create the C header
text = "/* %s - %d bytes */\n" \
"static const unsigned char %s%s_png[] = {\n" % (
filename, count, m.group(1), size_suffix)
# Iterate the characters, we want
# lines like:
# 0x01, 0x02, .... (8 values per line maximum)
i = 0
count = len(bytes)
for byte in bytes:
# Every new line starts with two whitespaces
if (i % 8) == 0:
text += " "
# Then the hex data (up to 8 values per line)
text += "0x%02x" % (byte)
# Separate all but the last values
if (i % 8) == 7:
text += ',\n'
elif (i + 1) < count:
text += ", "
i += 1
# Now conclude the C source
text += "};\n\n"
print text