// GD, png- :
ob_start ( ) ;
imagepng ( $img ) ;
imagedestroy ( $img ) ;
$img = ob_get_contents ( ) ;
ob_end_clean ( ) ;
// :
$img = file_get_contents ( 'path/fileName.png' ) ;
$dpi = 600 ; //
$incPos = strpos ( $img , 'IDAT' ) - 4 ; // chunk
$chunk = 'pHYs' . pack ( 'NNc' , round ( $dpi / 0.0254 ) , round ( $dpi / 0.0254 ) , 1 ) ; // chunk type + chunk data
$incData = pack ( 'N' , 9 ) . $chunk . pack ( 'N' , crc32 ( $chunk ) ) ; // chunk-, crc <br> file_put_contents ( 'path/fileName.png' , substr_replace ( $img , $incData , $incPos , 0 )) ; //
GDは単にpHYチャンクを作成しないという事実に注目します。 したがって、最初のIDATチャンクの前に挿入します。 ただし、任意のpng-shkaを使用する場合は、pHYチャンクが既に存在する場合を予測し、それを見つけて交換する必要があります。
チャンクの構成は、「 チャンクレイアウト」に記載されています 。
最初に、チャンクのコンテンツに割り当てられたバイト数を含む4バイトの符号なし整数があります(私たちの場合、9バイトが必要です)。 次に、チャンク名の4 ASCIIバイトが続きます( pHYに興味があります )。 次に、チャンクの内容である4バイトが幅に割り当てられ、4バイトが高さに割り当てられます。これらも符号なし整数です。 そして、1バイトを1に設定する必要があります。そうしないと、相対的な比率のみが設定されます。 その後、チャンクの名前と内容からCRC32チェックサムの4バイトを計算して書き込む必要があります。 重要! すべての数値変数(crcを含む)は鈍順(最高から最低)でなければならないことに注意してください。 メートルあたりのポイントで高さと幅を設定します。 したがって、1インチあたりのドット数を再計算するには、0.0254で割ります。
私の経験が誰かに役立つと思います。