PHPを使用してPNGにdpiを登録する

ここで、あるアプリケーションがPHPでPNG-shkiを生成し、後でそれらをドキュメントに挿入して印刷できるようにする必要がありました。 ただし、ここに問題があります。PHPでGDを使用して保存するときに解像度をdpiで設定することはできません。これは印刷するときに非常に重要です。 ImageMagickに参加したくなかったので、すぐにPNG(Portable Network Graphics)仕様をグーグルで調べ、このコードを書きました。

// 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で割ります。

私の経験が誰かに役立つと思います。

Source: https://habr.com/ru/post/J56588/


All Articles