読者です 読者をやめる 読者になる 読者になる

PHPでPNG画像を手軽に生成する

zlib関数を使えることが前提。
とは言っても、このページによると、

Zlibサポートを有効にするには、PHPコンパイル時にconfigureの オプションに--with-zlib[=DIR]を 指定してコンパイルする必要があります。
Windows 版の PHP には この拡張モジュールのサポートが組み込まれています。

とあるようにwinだとデフォルトで使える。

<?php

class PNGEncoder
{
    protected $h = null;
    function write($handle, Array $image)
    {
        $this->h = $handle;
        $this->writeHeader();
        $this->writeIHDRChunk(count($image[0]), count($image), 8, 2);
        
        $imagebody = '';
        foreach ($image as $line) {
            $imagebody .= pack('C', 0);
            foreach ($line as $pixel) {
                $imagebody .= pack('CCC', $pixel[0], $pixel[1], $pixel[2]);
            }
        }
        $this->writeIDATChunks($imagebody);
        $this->writeIENDChunk();
        $this->h = null;
    }
    protected function writeHeader()
    {
        fwrite($this->h, "\x89PNG\r\n\x1a\n");
    }
    protected function writeIHDRChunk($width, $height, $bit, $color)
    {
        $this->writeChunk('IHDR',
            pack('NNCCCCC', $width, $height, $bit, $color, 0, 0, 0));
    }
    protected function writeIDATChunks($body)
    {
        $this->writeChunk('IDAT', gzcompress($body));
    }
    protected function writeIENDChunk()
    {
        $this->writeChunk('IEND', '');
    }
    protected function writeChunk($name, $body)
    {
        $len = strlen($body);
        $crc = pack('N', crc32($name . $body));
        fwrite($this->h, pack('N', $len) . $name . $body . $crc);
    }
}

$b = array(0, 0, 0);       // 黒
$w = array(255, 255, 255); // 白
$image = array(array($w, $b, $w, $b),
               array($b, $w, $b, $w),
               array($w, $b, $w, $b),
               array($b, $w, $b, $w));

$h = fopen('test.png', 'w');
$encoder = new PNGEncoder;
$encoder->write($h, $image);
fclose($h);

これを実行して生成した画像が↓(見易いように五倍の大きさにしている)

生成した画像は白黒だけど、当然カラーのものも生成できる。
ただしアルファチャンネルやインターレース、ガンマ値などはサポートしていない。