我试图了解数据如何存储到IDAT块中.我正在写一个小
PHP类,我可以检索大部分块信息,但我得到的IDAT与我的图像的像素不匹配:
它是2×2px truecolour with alpha(bitdepth 8).
但是,当我解释这样的IDAT数据时:
current(unpack('H*',gzuncompress($idat_data)));
我明白了
00000000ffffff00ffffff000000
我不明白它是如何匹配像素的.或者是我的代码破坏了数据?
谢谢你的帮助!
编辑:我明白了
08d705c101010000008010ff4f1750a93029e405fb
作为十六进制压缩数据,因此在解压缩后我似乎丢失了几个字节.
使用gzinflate但跳过前2个字节,最后4个字节先跳过.
原文链接:https://www.f2er.com/php/137834.html$contents = file_get_contents($in_filename); $pos = 8; // skip header $color_types = array('Greyscale','unknown','Truecolour','Indexed-color','Greyscale with alpha','Truecolor with alpha'); $len = strlen($contents); $safety = 1000; do { list($unused,$chunk_len) = unpack('N',substr($contents,$pos,4)); $chunk_type = substr($contents,$pos+4,4); $chunk_data = substr($contents,$pos+8,$chunk_len); list($unused,$chunk_crc) = unpack('N',$pos+8+$chunk_len,4)); echo "chunk length:$chunk_len(dec) 0x" . sprintf('%08x',$chunk_len) . "h<br>\n"; echo "chunk crc :0x" . sprintf('%08x',$chunk_crc) . "h<br>\n"; echo "chunk type :$chunk_type<br>\n"; echo "chunk data $chunk_type bytes:<br>\n" . chunk_split(bin2hex($chunk_data)) . "<br>\n"; switch($chunk_type) { case 'IHDR': list($unused,$width,$height) = unpack('N2',substr($chunk_data,8)); list($unused,$depth,$Color_type,$Compression_method,$Filter_method,$Interlace_method) = unpack('C*',8)); echo "Width:$width,Height:$height,depth:$depth,Color_type:$Color_type(" . $color_types[$Color_type] . "),Compression_method:$Compression_method,Filter_method:$Filter_method,Interlace_method:$Interlace_method<br>\n"; $bytes_per_pixel = $depth / 8; break; case 'PLTE': $palette = array(); for($i=0;$i<$chunk_len;$i+=3) { $tupl = bin2hex(substr($chunk_data,$i,3)); $palette[] = $tupl; if($i && ($i % 30 == 0)) { echo "<br>\n"; } echo '<span style="color:' . $tupl . ';">[' . $tupl . ']</span>'; } echo print_r($palette,true) . "<br>"; break; case 'IDAT': $compressed = substr($chunk_data,2,$chunk_len - 6); // 2 bytes on the front and 4 at the end $decompressed = gzinflate($compressed); echo "decompressed chunk data " . strlen($decompressed) . " bytes:<br>\n" . chunk_split(bin2hex($decompressed),2 + $width * $bytes_per_pixel * 2) . "<br>\n"; for($row=0; $row<$height; $row++) { for($col=1; $col<=$width; $col++) { $index = (int)substr($decompressed,((int)$row*($width+1)+$col),1); echo '<span style="color:' . $palette[$index] . ';">' . $index . '</span>'; } echo "<br>\n"; } // TODO use filters described here: // http://www.w3.org/TR/PNG/#9Filters // first byte of scan line is filter type break; } $pos += $chunk_len + 12; echo "<hr>"; } while(($pos < $len) && --$safety);