PHPのGDで文字を描く

PHPで画像を扱うにはGDが楽なのですが、文字を書こうとすると思ったポイントで描画されません。
おそらくDPIを設定しないとだめなのでしょうが、PHPのリファレンスを探しても見つかりませんでした。
仕方がないのでいろいろ値をとりながら調べてみると、96dpiということが判明。
webではなくアプリケーション向けに72dpiで画像を生成するには以下のような手順となった。
ちなみに画像からはみ出にくいように調整もしてある。

$fontSize = 72;
$dpi = 96;
$margin = $fontSize / 8;
$baseline = $fontSize + $margin;
$size = $fontSize + $margin * 2;

$image = imagecreatetruecolor( $size, $size );

imageantialias( $image, true );
imagealphablending( $image, false );
imageSaveAlpha( $image, true );

$fillcolor = imagecolorallocatealpha( $image, 0, 0, 0, 127 );
imagefill( $image, 0, 0, $fillcolor );

$black = imagecolorallocate( $image, 0, 0, 0 );

$text = mb_convert_encoding( "あ", 'utf8' );
$font = 'xxxx.otf'; // 適当に置き換えて
imagettftext( $image, $fontSize/$dpi*$fontSize, 0, 0, $baseline, $black, $font, $text );

imagepng( $image, 'output.png', 9 );
imagedestroy( $image );

印刷も考えるとEPSで描いてから画像にするのが一番確実だけど、imagemagic(正確にはghostscript)を経由するのも面倒だしこうなった。

ヘッダ出力に手を抜いてハマる

PHPでの話です。といっても、PHPに限った話ではなさそうですが。
サーバでスクリプトを経由してファイルをダウンロードさせるには、Content-Typeさえ書いておけばとりあえず動いたりします。
さらにContent-Disposition: attachemnt; filename=”hoge.png”とでもしておけば、保存時のファイル名も指定できます。
で、これで満足してました。
通常の画像とかテキストであれば特に問題はなかったのですが、テキストで始まって途中にバイナリが混ざるファイル、そうPDFではだめでした。
PHPではバッファとか内部何とかとか、なくてもいい余計なものがたくさんあるので、それに振り回されます。
今回必要だったのは、mb_http_output(”pass”);
テキストで始まるものは強制的に内部エンコを行うためか、途中のバイナリが破壊されてしまうようです。それを回避するためのおまじない。
後、おまけとしてダウンロード完了までの時間を表示させるにはContent-Lengthでファイルサイズを送ってあげると親切なのかもしれません。
まぁ、しかし、これでPDFも正常にダウンロードできるようになりました。でめたしでめたし。

PHPのparse_ini_fileでハマる

parse_ini_fileは設定ファイルをパースしてくれる関数ですが、使い勝手が良いのか悪いのか。
文字列に「”」ダブルクオートを含む場合、そのままでは記述できません。
エスケープしてみたり、文字列をほかのもので囲んでみたりしたけど、希望するとおりにならない。
しかたなくphpのリファレンスを見ると、定数で逃げればいいとの事。
iniを動的に作成したりする場合は、

define( 'QUOTE', '"' );

必須ということですね。

こういうやり方が残っているとは、PHPもまだまだだなぁと思う今日この頃でした。
ちなみに、検索で調べた中で文字列自体を定数にしろという意見もありましたが、定数と変数の違いを理解していない人が多いのは残念です。
とはいえ、自分も定数に逃げている部分もあるので、大きいことはいえませんが。

WindowsでSMTP

Windowsでメールを送信するには、melonという便利ツールがあった。
http://seclan.dll.jp/download.htm

このツールを起動して、

phpで使いたかったので、php.iniは

; For Win32 only.
SMTP = localhost
smtp_port = 25

; For Win32 only.
sendmail_from = 127.0.0.1

これだけで、mail()やmb_send_mail()が使えるようになる。