Ωmega
Ωmega

Reputation: 43673

Getting image width and height from PNG without library

Based on specification of PNG (Portable Network Graphics) file, a very first chunk has to be IHDR (4 bytes), contains the image's width, height, and bit depth. So right behind IHDR are 4 bytes representing width and then next 4 bytes representing height of the image.

Is it safe to use regex /IHDR(.{4})(.{4})/s and convert $1 and $2 into width and height? If so, how can I do such conversion? Should I use unpack("N", $x) or unpack("V", $x) ..?


My current code (not sure if it works for large images):

if ($png =~ m/^\x89PNG\x0D\x0A\x1A\x0A....IHDR(.{4})(.{4})/s) {
  ($width, $height) = (unpack("N", $1) , unpack("N", $2));  
}

Upvotes: 2

Views: 721

Answers (2)

charri
charri

Reputation: 1052

This is an answer from 7 years later...

If you're processing the png at the binary level, the width is specified by the 17-20 bytes inclusive (17, 18, 19, 20) and the height is specified by the 21-24 bytes inclusive (21, 22, 23, 24).

Upvotes: 1

Guntram Blohm
Guntram Blohm

Reputation: 9819

I just looked up the png specification; there's more stuff in front of the IHDR. So this should work:

open(IN, "<xx.png");
binmode(IN);
read(IN, $header, 24);
if (substr($header, 12, 4) ne "IHDR") {
    die "this is not a PNG file";
}
($width, $height)=unpack("NN", substr($header, 16));
print "width: $width height: $height\n";
close IN;

Upvotes: 4

Related Questions