2013-12-11 3 views
2

на основе спецификации PNG файлов (Network Graphics Portable), очень first chunk должен быть IHDR (4 байта), содержит ширину, высоту и битовую глубину изображения. Итак, прямо за IHDR находятся 4 байта, представляющие width, а затем следующие 4 байта, представляющие height.Получение ширины и высоты изображения из PNG без библиотеки

Безопасно ли использовать регулярное выражение /IHDR(.{4})(.{4})/s и конвертировать $1 и $2 в width и height? Если да, то как я могу сделать такое преобразование? Должен ли я использовать unpack("N", $x) или unpack("V", $x) ..?


Мой текущий код (не уверен, если это работает для больших изображений):

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

ответ

3

Я просто смотрел на спецификацию в формате PNG; перед IHDR есть больше вещей. Так что это должно работать:

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; 
+0

При работе с двоичными данными, как в данном случае, я вообще предпочитаю SUBSTR() для регулярных выражений, потому что я не должен заботиться о специальных символов, таких как «\ п», которые указывают конец строки к регулярному выражению. –

+0

Да, есть 8-байтовый заголовок PNG и 4 байта, представляющий размер блока IHDR, за которым следует IHDR (4 байта/символов), ширина (4 байта), высота (4 байта), ... –

Смежные вопросы