I'm trying to tack on some information about the physical size for printing my PNGs just before they are generated.
Reading the libpng doc and the pHYs chunk specifications has been helpful but I just can't seem to crack it.
I have tried adding this chunk in the most manual and simplest way possible, however, the .png file ends up corrupted. Am I missing an encoding trick?
For the CRC computation I have used the 32-bit result of this site, having plugged in the ASCII values for the chunk that the code below gives me.
$encoded = $_POST['imgdata'];
$encoded = str_replace(' ', '+', $encoded);
$decoded= base64_decode($encoded);
$test = explode('IDAT',$decoded);
$ppu='00000000000000000010111000100011'; //32-bit integer for the pixels per unit
$dppu=bindec($ppu);
$test[0].=sprintf("%c",bindec('00000000000000000000000000001001')) //length, also 32-bit
.'pHYs' //type
. sprintf("%c",$dppu) //Pixels per unit, x axis
. sprintf("%c",$dppu) //Pixels per unit, y axis
.'1' //Units in metres (1 byte)
. sprintf("%c", bindec(base_convert('0x0BFAAA7E', 16, 2))) //CRC (32-bit)
.'IDAT';
$fintest=implode($test);
echo $fintest;
After having spent the day on this, I found that the way to do this was to translate everything byte by byte. Following the docs, the pHYs
chunk takes:
I wrote all this as a binary string, padding the bytes with 0 as necessary.
It then turns out that the chr()
function correctly encodes this to be used in the PNG file, unlike the sprintf("%c",$string)
method I use in the question. Here is the code
$encoded = $_POST['imgdata'];
$encoded = str_replace(' ', '+', $encoded);
$decoded= base64_decode($encoded);
$binstring='00000000000000000000000000001001' //4-byte length
. '01110000010010000101100101110011' //4-byte type or 'pHYs'
. '000000000000000000101110001000110000000000000000001011100010001100000001' //9-byte data
. base_convert('0x0BFAAA7E', 16, 2); //4-byte CRC
foreach (str_split($binstring,8) as $b) {
$on.=chr(bindec($b));
}
The $on variable is then appended to the position just before the 4 bytes of the IDAT
chunk length.