Core Graphicsでサムネイル作成

php_cgthumbnail-071023.zip
php_cgthumbnail-071025.zip

  • Photoshop出力で落ちるバグを修正。
  • Core GraphicsではQuickTime Imageフォーマットは読み込み専用だったので、出力フォーマットから除外。
  • オプションのパージングにいくつか問題があったのを修正。

php_cgthumbnail-071026.zip

  • バグ修正。
  • CPPFLAGS=-DCGT_WITH_GD=1 でmakeするとGD Image <-> Core Graphics Image変換関数が使えるようになった。(同梱のユニバーサルバイナリは非対応)
    • resoure cgreadimage(string $filename[, string $password])
      • $filenameから画像を読み込んでGDイメージリソースとして返す。
    • mixed cgwriteimage(resource $image[, string $filename[, string $type[, int $compression]]])
      • GDイメージリソースを$typeで指定した形式 (デフォルトはPNG) で$filenameに書き出す。
      • 書き出しに成功したらtrue、失敗したらfalseを返す。
      • $filenameを省略するか、空文字列またはnullを指定した場合は画像データをバイナリ文字列として返す。


Mac専用の画像サムネイルを作成するPHPエクステンションを作ってみました。アーカイブにはソースコードのほか、PHP 5.2向けのユニバーサルバイナリ (cgthumbnail-ub-php52-no-debug-non-zts.so) も入っています。LeopardPHPは5.2.4らしいので、そのまま使えるかもしれません。


このエクステンションは関数 bool cgthumbnail(string $src_filename, string $dst_filename[, mixed $size[, array $options]]) ただ一つがあるだけです。$src_filename はソース画像のパス名、$dst_filename はサムネイルを書き出すパス名、$size はサムネイルの大きさ、$options は変換オプションを指定します。サムネイルの作成に成功したらtrue、失敗したらfalseを返します。
読み込み可能なファイル形式はPDFも含めたPreview.appで表示できるファイル形式すべて (たぶん) で、書き出し可能なファイル形式はJPEG, JPEG2000, TIFF, PICT, GIF, PNG, QuickTime Image, BMP, Photoshop, SGI, Targaです。オリジナルの色空間に関係なく8bits/pixelのRGBとして書き出します。


では実際に暗号化されたPDFのサムネイルを作ってみましょう。

<?php
extension_loaded('cgthumbnail') || dl('cgthumbnail.so');
cgthumbnail('phppro_200704/phppro_200704.pdf', 'thumb.png', 300, array('password' => '********'));
?>


このように簡単にサムネイルを作ることができます。

オプション引数について

$size
説明
(省略) - リサイズしない。
整数 120 正方形の1辺の大きさ。
0のときはリサイズしない。
文字列 (縮小率) "50%" オリジナルの大きさからの比率。
文字列 (幅と高さ) "320 240"
"320,240"
"320x240"
区切り文字は半角スペース、カンマ、小文字のxのいずれかからひとつだけ。
一方が0のときはもう一方に合わせてリサイズする。
両方が0のときはリサイズしない。
配列 (幅と高さ) array(320, 240) 添字は必ず幅が0、高さが1であること。
0の扱いは上に同じ。
$options
キー 説明
type string "jpg" 出力ファイル形式。jpg (jpeg), jp2 (jpeg2000), tif (tiff), pct (pict), gif, png, qif (qtif, quicktime), bmp, psd (photoshop), sgi, tga (targa) のいずれか。大文字小文字は無視する。
通常は$dst_filenameの拡張子から自動で設定される。拡張子からファイル形式を判定できなかったときのデフォルトの形式はPNG
cropRect array
string
array(10, 10, 120, 120)
"10,10,120,120"
画像を切り取る領域。画像の左下左上を(0,0)として、X軸の始点、Y軸の始点、幅、高さの順で表す。
配列の場合、添字は順番に0から3であること。文字列の場合、区切り文字はカンマひとつだけ。
デフォルトではクロップしない。
keepAspect boolean false falseなら画像の縦横比を無視して指定されたサイズに合わせる。デフォルトではtrue。
scaleDownOnly boolean false trueなら指定されたサイズがオリジナルより大きいときは拡大しない。デフォルトではtrue。
saveAlpha boolean false trueなら画像の透明度を維持する。デフォルトではtrue。
backgroundColor array
string
array(255, 160, 128)
array(255, 160, 128, 128)
"rgb(255,160,128)"
"rgba(255,160,128,128)"
"#ffa080"
画像の背景色。0から255までのRGBまたはRGBAで指定する。
デフォルト値はないが、JPEGのように透明度を持つことができない画像形式の場合は白が適用される。
compression integer 90 JPEGおよびJPEG2000の圧縮率。0から100までの整数で指定する。
TIFFの場合は0なら非圧縮、それ以外ならLZW圧縮が適用される。
デフォルト値は90。
password string "hoge" 暗号化されたPDFのパスワード。

インストール方法

Leopardコンパイル済みユニバーサルバイナリをインストール:

cd cgthumbnail-071023
EXTENSION_DIR=`/usr/bin/php-config --extension-dir`
sudo mkdir -p "$EXTENSION_DIR"
sudo install -c cgthumbnail-ub-php52-no-debug-non-zts.so "$EXTENSION_DIR/cgthumbnail.so"

ソースから:

cd cgthumbnail-071023/cgthumbnail
make
sudo make install
make clean

ユニバーサルバイナリとして:

cd cgthumbnail-071023/cgthumbnail
make universal
sudo make install-universal
make clean

php-configで対象のPHPを指定して:

cd cgthumbnail-071023/cgthumbnail
PHP_CONFIG=/opt/php/6.0/bin/php-config make
PHP_CONFIG=/opt/php/6.0/bin/php-config sudo make install
make clean

以下余談

当初はCocoa (AppKit)のNSImageクラスを使って作成していたのですが、WebサーバからはWindowServerを利用できない (させてもらえない) のでCore Imageで書き直し、この用途ではCore Imageを使う必要があまり無かったのと、PDFに対応したかったのでCore Graphicsで書き直しとなりました。それにともなってコードの中のCocoa API (Objective-C)が占める割合が減り、Core GraphicsのAPI (C)が増えていきました。そして、今では各種パラメータをFoundationフレームワークのクラスで初期化してからCore Foundationのオブジェクトにキャストする以外のObjective-Cのコードはなくなっています。しかしそれでも自動解放プールが超便利なので全部Core Foundationで書こうとは思いません。Tool-free bridgeバンザイ。
ちなみにPHPエクステンションでも配列を自動解放プールとして使うテクニックがあり、拙作のLibYAMLバインディングではその方法を使っています。が、そもそも一時的なzvalをヒープメモリにたくさん作る機会があまりないので、それが便利になる場合も少なかったりします。