PHP5上級試験/準上級試験の上級合格に挑戦(17) プログラミングPHP第3版 9章

# ９章　グラフィックス
※ 黒本には載ってない部分を基本的に掲載していく

phpファイルで画像も作れる（ex. image1.phpなど）
これにパラメータを指定することもできる
（ex. \<img src="image1.php?num=1">とか、\<img src="image1.php?text=ok"> とか)
※たとえば$_GET['num']とかしてパラメータによって画像を変化させる、、、なんてこともできる

逆に画像タグからok.pngを生成するPHPスクリプトを起動させることもできる
（ex. \<img src="buttons/ok.png"> など）

基本グラフィックス作成コード

```index.php
//imageキャンパスを作る
$image = imagecreate(200,200);
//色を変数に格納
$white = imagecolorallocate($image,0xFF,0xFF,0xFF);
$black = imagecolorallocate($image,0x00,0x00,0x00);
//塗りつぶされた正方形を作成
imagefilledrectangle($image,50,50,150,150,$black);

//具現化
header("Content-Type: image/png");
imagepng($image);
```

## 9.3.3 サポートする画像のフォーマットの確認
複数の環境で動作させる場合にはimagetypes()で、その環境が適しているタイプを調べることができる

```index.php
//imageキャンパスを作る
$image = imagecreate(200,200);
//色を変数に格納
$white = imagecolorallocate($image,0xFF,0xFF,0xFF);
$black = imagecolorallocate($image,0x00,0x00,0x00);
//塗りつぶされた正方形を作成
imagefilledrectangle($image,50,50,150,150,$black);

//調べてその設定で送信
if (imagetypes() & IMG_PNG){
 header("Content-Type: image/png");
 imagepng($image);
}
else if (imagetypes() & IMG_JPG){
 header("Content-Type: image/jpg");
 imagepng($image);
}
else if (imagetypes() & IMG_GIF){
 header("Content-Type: image/gif");
 imagepng($image);
}

```
## 9.4.2 TrueTypeFont

TrueTypeはアウトラインフォントの標準規格。
これを追加するには imagettftextを使う
 imagettftext(image,size,angle,x,y,color,font,text)

```index.php
//通常はこんな感じ
//imageキャンパスを作る
$image = imagecreate(350,70);
//色を変数に格納
$white = imagecolorallocate($image,0xFF,0xFF,0xFF);
$black = imagecolorallocate($image,0x00,0x00,0x00);

//GDがTrueTypeフォントを探すパスを設定
putenv("GDFONTPATH=" . realpath('.'));
imagettftext($image, 20, 0, 10, 40, $black, 'courbi',"Courier TrueType"));

 header("Content-Type: image/png");
 imagepng($image);

```

```index.php
//縦書きはこんな感じ
//imageキャンパスを作る
$image = imagecreate(70,350);
//色を変数に格納(RGB形式で記載も可能）
$white = imagecolorallocate($image,255,255,255);
$black = imagecolorallocate($image,0,0,0);

//GDがTrueTypeフォントを探すパスを設定
putenv("GDFONTPATH=" . realpath('.'));
//270は上から下に向かう縦書きになる　９０度は逆
imagettftext($image, 20, 270, 28, 10, $black, 'courbi',"Courier TrueType"));

 header("Content-Type: image/png");
 imagepng($image);

```

## 9.5 動的に作成するボタン

```index.php
$font = "times";
$size = isset($_GET['size']) ? $_GET['size] : 12;
$text = isset($_GET['text'] ? $_GET['text'] : '';

$image = imagecreatefrompng("button.png");
$black = imagecolorallocate($image,0,0,0);


if ($text){
  $tsize = imagettfbbox($size, 0, $font, $text);
  $dx = abs($tsize[2] - $tsize[0]);
  $dy = abs($tsize[5] - $tsize[3]);
  $x = (imagesx($image) - $dx) / 2;
  $y = (imagesy($image) - $dy) / 2 + $dy;

  //text描画
　imagettftext($image, $size, 0, $x, $y, $black, $font, $text);
}

header("Content-Type: image/png");
imagepng($image);

```
上記で無地のボタンが作れる。
そして、パラメータを下記のようにすると、パラメータがボタンに表記される。

```index.php
<img src="button.php?text=PHP+Button" />
```
スペースが＋になる
でもエンコードするなら

```index.php
<img src="button.php?text=<?= urlencode("PHP+Button"); ?>" />
```
となる。


## 9.5.1 ボタンのキャッシュ

ボタンのキャッシュを簡易的に作成

```index.php
$font = "times";
$size = isset($_GET['size']) ? $_GET['size] : 12;
$text = isset($_GET['text'] ? $_GET['text'] : '';

$path = "/tmp/buttons"; //ボタンをキャッシュするディレクトリ

//キャッシュ内容を送信(新規に書いた部分）
if ($bytes = @filesize("{$path}/{$text}.png")) {
 header("Content-Type: image/png");
 header("Content-Length: {$bytes}");
 exit;
} 

//画像作成して送信、キャッシュ
$image = imagecreatefrompng("button.png");
$black = imagecolorallocate($image,0,0,0);


if ($text){
  $tsize = imagettfbbox($size, 0, $font, $text);
  $dx = abs($tsize[2] - $tsize[0]);
  $dy = abs($tsize[5] - $tsize[3]);
  $x = (imagesx($image) - $dx) / 2;
  $y = (imagesy($image) - $dy) / 2 + $dy;

  //text描画
　imagettftext($image, $size, 0, $x, $y, $black, $font, $text);
  //画像をファイルに保存（新規に書いた部分）
　imagepng($image, "{$path}/{$text}.png");
}

header("Content-Type: image/png");
imagepng($image);

```

## 9.5.2 より高速なキャッシュ

Apacheのディレクティブを使うとPHPスクリプトを作らずして一度作った画像をキャッシュから読み込める

１）　Webサーバーのドキュメントルート配下のどこかにbuttonsというディレクトリを作成
２）　Apacheのhttpd.confファイルに以下を追加
   (buttonsディレクトリにないファイルがリクエストされたら、button.phpを実行させる指定）

```index.php
<Location /buttons/>
 ErrorDocument 404 /button.php
</Location>
```
3) 以下をbutton.phpとして保存でOK

```index.php

//リダイレクト前のURLのパラメータがあれば取得
parse_str($_SERVER['REDIRECT_QUERY_STRING']);

$cacheDir = "/buttons/";
$url = $_SERVER['REDIRECT_URL'];
//拡張子ゲット
$extension = substr($url, strrpos($url,'.'));

//文字列＄urlからディレクトリと拡張子を取り除く
$file = substr($url, strlen($cacheDir), -strlen($extension));

//ファイル名から..を取り除く
$file = str_replace('..','',$file);

//ボタンに表示するテキスト
$text = urldecode($file);

$font = "times";
$path = "/tmp/buttons"; //ボタンキャッシュディレクトリ

//画像作成して送信、キャッシュ
$image = imagecreatefrompng("button.png");
$black = imagecolorallocate($image,0,0,0);

//テキストの位置を算出
if ($text){
  $tsize = imagettfbbox($size, 0, $font, $text);
  $dx = abs($tsize[2] - $tsize[0]);
  $dy = abs($tsize[5] - $tsize[3]);
  $x = (imagesx($image) - $dx) / 2;
  $y = (imagesy($image) - $dy) / 2 + $dy;

  //text描画
　imagettftext($image, $size, 0, $x, $y, $black, $font, $text);
  //画像をファイルに保存（新規に書いた部分）
　imagepng($image, "$_SERVER['DOCUMENT_ROOT']}{$cacheDir}{$file}.png");
}

header("Content-Type: image/png");
imagepng($image);

```
※ファイル名として使用可能な文字しかボタンにできない
*ボタンを変えた場合はキャッシュにあるファイルを除去すれば新たに作成される
*ちょっと上でやったように画像形式を変えることもサイズを変えることも可能
　サイズはパラメータで指定すればOK（http://example.com/buttons/php.png?size=16 など）

## 9.7 色の処理
(1) ７ビットのアルファチャンネルがあるフルカラーの画像を作成する関数は？
(2) 8ビットのパレット形式画像を作成する関数は？
(3) imagecolorallocate（）で最初に指定した色はどこに使う？
(4) 透明度情報を含む色インデックスを作成する


(1) imagecreatetruecolor()
(２) imagecreate()
(3) 背景色
(4) imagecolorallocatealpha(image,red,green,blue,alpha)