Getting PNG image info
Posted: 30 Oct 2015, 22:39
Hi, I just wanted to share a function to get a PNG image's info, like its width, height, bits per pixel, etc. It's accomplished by simply reading the first 33 bytes of the file. The other methods I saw required using DLLs (GDIp), or creating a hidden GUI picture control, or shelling out to run IrfanView....all of them a bit overly complicated in my opinion. Here's the code:
It's obviously limited to PNG files, but that's all I need currently (maybe I'll add JPG, BMP, GIF later). Here's a simple example to print out (to STDOUT) the info for all PNG images in a folder:
Comments/questions/critiques are welcome.
Code: Select all
get_png_image_info(filename) {
file := FileOpen(filename, "r")
if !IsObject(file)
{
print_line("Error: Can't open '" filename "' for reading.")
return
}
; note: PNG is stored in big-endian format
signature := file.ReadInt64()
if signature != 0xa1a0a0d474e5089
{
print_line("Error: Not a PNG file")
return
}
file.ReadUInt() ; skip 4 bytes (IHDR's length)
IHDR_tag := file.ReadInt()
if IHDR_tag != 0x52444849
{
print_line("Error: IHDR expected as first chunk.")
return
}
width := byte_swap_32(file.ReadUInt())
height := byte_swap_32(file.ReadUInt())
bpp := file.ReadUChar() ; valid values are 1, 2, 4, 8, and 16
colortype := file.ReadUChar() ; valid values are 0, 2, 3, 4, and 6.
compression := file.ReadUChar() ; usually 0 for deflate/inflate
filter := file.ReadUChar() ; usually 0
interlace := file.ReadUChar() ; 0 = none, 1 = Adam7
return { width: width
, height: height
, bpp: bpp
, colortype: colortype
, compression: compression
, filter: filter
, interlace: interlace
, filename: filename }
}
; change endian-ness for 32-bit integer
byte_swap_32(x) {
return ((x >> 24) & 0xff)
| ((x << 8) & 0xff0000)
| ((x >> 8) & 0xff00)
| ((x << 24) & 0xff000000)
}
print_line(str) { ; output line to STDOUT for debugging in my text editor (sublime)
FileAppend, %str%`n, *
}
Code: Select all
Loop, Files, d:\pics\*.png
{
imageInfo := get_png_image_info(A_LoopFileFullPath)
if imageInfo
{
print_line("""" imageInfo.filename """`n`t"
. "width: " imageInfo.width
. ", height: " imageInfo.height
. ", bpp: " imageInfo.bpp
. ", color type: " imageInfo.colortype
. ", compression: " imageInfo.compression
. ", filter: " imageInfo.filter
. ", interlace: " imageInfo.interlace)
}
}