Reputation: 43673
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
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
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