PHPのGDを使って市松模様(checkered pattern)を出力する

PHPのGDのみを使って市松模様を出力します。
通常、このような画像を作るときはPhotoshopなどの画像処理ソフトでパパっとやっちゃいますが
PHPだけでも出来るよということで何年も前に書いた関数です。

GDはPHP使えればレンタルサーバ等の機能を絞られた環境でも大抵使えるので
そういった案件ではお世話になることも多いです。

GDで透明度を設定するとき
今回はimagecolorallocatealpha関数を使用しますが
**透明度を設定するときは0から127の128段階です。
RGBの値はそれぞれ#000000のような16進数カラーコード同様256段階なので注意が必要です。**
この関数では色を指定するときは16進数カラーコード(アルファ付きの8桁)で指定しますが
近似値に変換しています。

出力例です。白とグレーの市松模様は透明色に見えます。不思議ですね。
![transparent.php.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387171/a5550789-f85c-bceb-8df5-4c008928bb82.png)

```
<?php
/**
 * create_checkered_pattern_image
 *
 * 市松模様を出力する
 * みる人がみたら透過色にみえる不思議
 *
 * @param  integer  $width      画像幅
 * @param  integer  $height     画像高
 * @param  integer  $gridSize   グリッド(升目)の大きさ
 * @param  string   $bgColor    背景色(6桁、もしくはアルファを含む8桁のカラーコード(#000000 or #00000000))
 * @param  string   $fillColor  塗り色(6桁、もしくはアルファを含む8桁のカラーコード(#000000 or #00000000))
 * @param  string   $format     画像フォーマット(jpeg, gif, pngいずれか)
 *
 * // 直接出力する場合
 * header('content-type: image/' . $format);
 * create_checkered_pattern_image($width, $height, $gridSize, $bgColor, $fillColor, $format);
 *
 * // htmlタグを出力する場合、$base64encodeを真にする
 * echo '<img src="data:image/' . $format . ';base64,' . create_checkered_pattern_image($width, $height, $gridSize, $bgColor, $fillColor, $format, true) . '">';
 */

// 例: 透明っぽい市松模様

// 画像幅
$width = 240;
// 画像高
$height = 240;
// グリッド(升目)の大きさ
$gridSize = 20;
// 背景色(6桁、もしくはアルファを含む8桁のカラーコード(#000000 or #00000000))
$bgColor = '#ffffff';
// 塗り色(6桁、もしくはアルファを含む8桁のカラーコード(#000000 or #00000000))
$fillColor = '#afafaf';
// 画像フォーマット(jpeg, gif, pngいずれか)
$format = 'png';

header('content-type: image/' . $format);
echo create_checkered_pattern_image($width, $height, $gridSize, $bgColor, $fillColor, $format);

function create_checkered_pattern_image($width, $height, $gridSize, $bgColor, $fillColor, $format = 'png', $base64encode = false, $reverse = false) {

    // カラーコードであるか
    $colorCodeRegex = '/^(?:#)?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i';

    // jpg = jpeg
    if ($format == 'jpg') $format = 'jpeg';

    if (preg_match($colorCodeRegex, $fillColor, $color)) {
        $fillRed = $color[1];
        $fillGreen = $color[2];
        $fillBlue = $color[3];
        if (isset($color[4])) $fillAlpha = $color[4];
    } else {
        return false;
    }
    if (preg_match($colorCodeRegex, $bgColor, $color)) {
        $bgRed = $color[1];
        $bgGreen = $color[2];
        $bgBlue = $color[3];
        if (isset($color[4])) $bgAlpha = $color[4];
    } else {
        return false;
    }

    if (!in_array($format, array('gif', 'jpeg', 'png'))) return false;

    $image = imagecreate($width, $height);
    if (isset($bgAlpha)) {
        $bg = imagecolorallocatealpha($image, hexdec($bgRed), hexdec($bgGreen), hexdec($bgBlue), create_checkered_pattern_image_alpha_convert($bgAlpha));
    } else {
        $bg = imagecolorallocate($image, hexdec($bgRed), hexdec($bgGreen), hexdec($bgBlue));
    }
    if (isset($fillAlpha)) {
        $fill = imagecolorallocatealpha($image, hexdec($fillRed), hexdec($fillGreen), hexdec($fillBlue), create_checkered_pattern_image_alpha_convert($fillAlpha));
    } else {
        $fill = imagecolorallocate($image, hexdec($fillRed), hexdec($fillGreen), hexdec($fillBlue));
    }

    $i = 0;
    for ($y = 0; $y <= $height; $y += $gridSize) {
        if (!$reverse) {
            $i++;
        }
        $i % 2 == 0 ? $s = 0 : $s = $gridSize;
        for ($x = $s; $x < $width; $x += $gridSize * 2) {
            imagefilledrectangle($image, $x, $y, $x + $gridSize - 1, $y + $gridSize - 1, $fill);
        }
        if ($reverse) {
            $i++;
        }
    }

    if ($base64encode) {
        ob_start();
    } else {
        header('content-type: image/' . $format);
    }

    switch ($format) {
        case 'gif':
            imagegif($image);
            break;
        case 'jpeg':
        case 'jpg':
            imagejpeg($image, null, 100);
            break;
        case 'png':
            imagepng($image);
            break;
    }

    if ($base64encode) {
        $ob = ob_get_contents();
        ob_clean();

        return base64_encode($ob);
    }

}

function create_checkered_pattern_image_alpha_convert($in) {
    return (int) floor((hexdec($in) / 2 ) - 127) * -1;
}
```