उपयोग gzinflate के साथ प्रयास करें, लेकिन पहले 2 बाइट्स और पिछले 4 को छोड़ पहले चाहते हैं।
$contents = file_get_contents($in_filename);
$pos = 8; // skip header
$color_types = array('Greyscale','unknown','Truecolour','Indexed-color','Greyscale with alpha','unknown','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', substr($contents,$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,0,8));
list($unused,$depth,$Color_type,$Compression_method,$Filter_method,$Interlace_method) = unpack('C*', substr($chunk_data,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);
धन्यवाद के लिए फ़िल्टर प्रकार होना चाहिए, धन्यवाद अब काम करता है लेकिन मुझे "00000000ffffff00ffffff000000 मिलता है "(14 बाइट्स), वे पिक्सल पाने के लिए कैसे उपयोग किए जाते हैं? – MatTheCat
अच्छा संपीड़न प्राप्त करने के लिए, पीएनजी प्रारूप संपीड़न से पहले फ़िल्टर लागू करता है। फ़िल्टर इस तरह की चीजें करते हैं: यदि दो स्कैन लाइन एक-दूसरे-द-दूसरे लगभग समान हैं, तो नीचे की पिक्सेल से मेल खाने वाली निचली रेखा पर पिक्सल, शून्य में बदल जाते हैं। तो जब आप कर लेंगे तो आपके पास शून्य का एक बकवास-टन है और संपीड़न वास्तव में अच्छा है। तो आपको डिकंप्रेशन के बाद फ़िल्टर को पूर्ववत करने और * पूर्ववत करने की आवश्यकता है। देखें http://www.w3.org/TR/PNG/#9 फ़िल्टर – Charlie
दाएं, और फ़िल्टर "एक स्कैनलाइन में बाइट अनुक्रम को फ़िल्टर प्रकार बाइट से पहले बाइट्स के बराबर लंबाई अनुक्रम में बदल देता है"। तो क्या मेरे पास 18 बाइट असम्पीडित डेटा नहीं होना चाहिए (1 "बाइटपेथ" * 4 चैनल * 4 पिक्सल + 2 फ़िल्टर)? – MatTheCat