あけましておめでとうございます。本年1発目の記事は、元webブログらしく技術的なやつで。
プログラミングはPerlから入ったのもあって、ImageMagickをPerlで使う方法しか知りませんでした。(というか、ImageMagick使いたくてPerl勉強した)
先日リリースした「カラログ」や「ソウルジェムメーカー」を制作している時、全部PHPやりたいなぁというのもあり、Imagickの使い方を勉強しました。
そんなわけで、勉強したことをシェアしておきます。
/* 2019.1.7追記 */
サンプルが表示されなくなっていたので、修正しました。環境によってはフルパスでないとエラーになるようです。
読み込みや書き出しのファイル名は$rfilename = realpath($filename);
などして、フルパスに置き換えてください。
Contents
ImageMagickとImagickの違いについて
PHPでImageMagickを使いたい!となったとき、Imagickというのが出てきて、そこでよく分からなくなってたんですが、違いを調べたらなるほど納得。
ImageMagick | C言語で書かれた画像処理ソフトウェア・ライブラリ |
---|---|
Imagick | PHPからImageMagickを操作するためのPHP拡張モジュール |
Image::Magick(PerlMagick) | PerlからImageMagickを操作するためのPerlモジュール |
これが分かってから、すんなりサンプルが読めるようになりました。なるほどです。
参考)
[PHP]ImageMagickとImagickの違いについてそろそろ一言いっておくか。 – DQNEO起業日記
[Perl]ImageMagickとImage::Magickの違いについてそろそろ一言いっておくか。 – DQNEO起業日記
以下は自分がよく使うImagickのサンプルです。
よく使うImagickのサンプル
使用した元画像)
※素敵な薬棚の写真は無料写真素材ぱくたそからお借りしました。
画像の読み込み&表示
<?php // 画像の読み込み&表示 $filename = "../img/phpmagick1.jpg"; //読み込むファイル名 /* 画像の読み込み */ $image = new Imagick($filename); /* 画像を出力 */ header("Content-Type: image/jpeg"); //表示する画像ヘッダー echo $image; $image->clear(); ?>
実行結果
サンプル1
画像の読み込み&書き出し
<?php // 画像の読み込み&書き出し $filename1 = "../img/phpmagick1.jpg"; //読み込むファイル名 $filename2 = "phptest.jpg"; //書き出すファイル名 $image = new Imagick($filename1); $image->writeImage($filename2); /* ブラウザの出力 */ header("Content-Type: text/html"); echo "Complete!<br>"; echo '<img src="'.$filename2.'" />'; $image->clear(); ?>
実行結果
サンプル2
※リンク先では「Complete!」の文字と書き出された画像が表示されます。
フォーマット変更
<?php // フォーマットの変更 $filename = "../img/phpmagick1.jpg"; //読み込むファイル名 /* 画像の読み込み */ $image = new Imagick($filename); $image->setImageFormat('gif'); /* 画像を出力 */ header("Content-Type: image/gif"); //表示する画像ヘッダー echo $image; $image->clear(); ?>
実行結果
サンプル3
分かりにくいですが、jpeg画像がgif画像として表示されています。
「setImageFormat(‘gif’)」の部分と画像ヘッダーの「header(“Content-Type: image/gif”);」のgifをpngにすれば、png画像として表示や書き出しをすることが出来ます。
サイズ変更
<?php // 画像のサイズ変更 $filename = "../img/phpmagick1.jpg"; //読み込むファイル名 /* 画像の読み込み */ $image = new Imagick($filename); $image->thumbnailImage(100, 0); /* 画像を出力 */ header("Content-Type: image/jpeg"); //表示する画像ヘッダー echo $image; $image->clear(); ?>
実行結果
サンプル4
縦横比を維持したままリサイズする場合は、thumbnailImage(100, 0)のどちらかを0にすることで出来ます。
縦横比を無視する場合は、両方に値を設定します。
また、今回はthumbnailImageを使用しましたが、他にもresizeImageやscaleImageなどがあります。
どれを使うのが良いのか?という疑問については以下の記事が参考になると思います。
参考)PECL::Imagick で画像リサイズ処理する場合どれ使えばいいか – (0 3 0)
サムネイルを作る
<?php // サムネイルを作る $filename = "../img/phpmagick1.jpg"; //読み込むファイル名 $thumbname = "thumb.jpg"; //サムネイルのファイル名 /* 画像の読み込み */ $image = new Imagick($filename); /* サムネイルの作成 */ $thumbImg = $image->clone(); $thumbImg->thumbnailImage(100, 0); $thumbImg->writeImage($thumbname); /* ブラウザの出力 */ header("Content-Type: text/html"); echo "Complete!<br>"; echo '<img src="'.$filename.'" /><br>'; echo '<img src="'.$thumbname.'" />'; $image->clear(); $thumbImg->clear(); ?>
実行結果
サンプル5
※リンク先では「Complete!」の文字と読み込んだ画像と作成されたサムネイル画像が表示されます。
$image->clone();で読み込んだ画像のコピーを作成し、そのコピーをリサイズしています。
画像を重ねる
<?php // 画像を重ねる $filename1 = "../img/phpmagick1.jpg"; //読み込むファイル名 $filename2 = "../img/phpmagick2.png"; //重ねる画像ファイル名 /* 画像の読み込み */ $image1 = new Imagick($filename1); $image2 = new Imagick($filename2); /* image1にimage2を重ねる パラメータの3番目がx、4番目がyの位置 */ $image1->compositeImage( $image2, imagick::COMPOSITE_DEFAULT, 130, 0 ); ob_clean(); // おそうじ /* 画像を出力 */ header("Content-Type: image/jpeg"); //表示する画像ヘッダー echo $image1; $image1->clear(); $image2->clear(); ?>
実行結果
サンプル6
重ねる画像を半透明にしたい場合は、以下のようにすると可能です。
//重ねる画像を半透明にしてから重ねる。1.0が不透明、0.0で完全な透明 $image2->evaluateImage(Imagick::EVALUATE_MULTIPLY, 0.5, Imagick::CHANNEL_ALPHA); $image1->compositeImage( $image2, imagick::COMPOSITE_DEFAULT, 130, 0 );
実行結果
サンプル6(PNG半透明)
重ねている画像が透過PNGなので上記の方法でしたが、透過PNGでない場合は、以下のようにsetImageOpacityで出来ます。
//重ねる画像を半透明にしてから重ねる。1.0が不透明、0.0で完全な透明 $image2->setImageOpacity(0.7); $image1->compositeImage( $image2, imagick::COMPOSITE_DEFAULT, 50, 50 );
実行結果
サンプル6(JPEG半透明)
色を変える
<?php // 色を変える $filename1 = "../img/phpmagick1.jpg"; //読み込むファイル名 $filename2 = "../img/phpmagick2.png"; //重ねる画像ファイル名 /* 画像の読み込み */ $image1 = new Imagick($filename1); $image2 = new Imagick($filename2); /* カラーコードを指定して色を変えられます。二番目のパラメータは不透明度 */ //$image1->colorizeImage('#ff0000', 1.0); //$image2->colorizeImage('#00ff00', 1.0); $image1->setImageAlphaChannel(Imagick::ALPHACHANNEL_EXTRACT); $image1->setImageBackgroundColor('#ff0000'); $image1->setImageAlphaChannel(Imagick::ALPHACHANNEL_SHAPE); $image2->setImageAlphaChannel(Imagick::ALPHACHANNEL_EXTRACT); $image2->setImageBackgroundColor('#00ff00'); $image2->setImageAlphaChannel(Imagick::ALPHACHANNEL_SHAPE); $image1->compositeImage( $image2, imagick::COMPOSITE_DEFAULT, 130, 0 ); ob_clean(); // おそうじ /* 画像を出力 */ header("Content-Type: image/jpeg"); //表示する画像ヘッダー echo $image1; $image1->clear(); $image2->clear(); ?>
実行結果
サンプル7
colorizeImageの二番目のパラメータは、色味を変えるのが目的なら1でも0でも結果は同じになります。
/* 2019.1.7 修正 */
colorizeImageで色が変わらない場合、setImageBackgroundColorで変えることができます。
効果を付ける
<?php // 効果をつける(油絵調) $filename = "../img/phpmagick1.jpg"; //読み込むファイル名 /* 画像の読み込み */ $image = new Imagick($filename); $image->oilPaintImage(false); /* 画像を出力 */ header("Content-Type: image/jpeg"); //表示する画像ヘッダー echo $image; $image->clear(); ?>
実行結果
サンプル8(油絵調)
油絵調の他にも、色んな効果があります。
にじみ
$image->blurImage(5,3); //パラメータ1はにじみの半径、2は標準偏差
実行結果
サンプル8(にじみ)
エンボス加工
$image->embossImage( 0, 1 ); //パラメータ1は効果の半径、2は効果のシグマ
実行結果
サンプル8(エンボス)
ネガ反転
$image->negateImage(false);
実行結果
サンプル8(ネガ反転)
他にも色々な加工ができますので、やってみると面白いですよ。
文字を書く
<?php // 文字を書く $filename = "../img/phpmagick1.jpg"; //読み込むファイル名 /* 画像の読み込み */ $image = new Imagick($filename); /* のせる文字を書く */ $draw = new ImagickDraw(); $draw->setFontSize('24'); // フォントサイズ $draw->setFillColor('#ff0000'); // 文字色 $draw->annotation(10, 100, "I Love Magick"); /* ImagickDraw をキャンバス上に描画します */ $image->drawImage($draw); /* 画像を出力 */ header("Content-Type: image/jpeg"); //表示する画像ヘッダー echo $image; $draw->clear(); $image->clear(); ?>
実行結果
サンプル9
drawオブジェクトを生成してテキストを書き、それを画像にのせる、というイメージだと分かりやすいかもしれません。
$filename = "../img/phpmagick1.jpg"; //読み込むファイル名 $fontName = '/home/〜/APJapanesefont.ttf'; //フォントファイルまでのパス /* 画像の読み込み */ $image = new Imagick($filename); /* のせる文字を書く */ $draw = new ImagickDraw(); $draw->setFont($fontName); //フォントの指定 $draw->setFontSize('24'); // フォントサイズ $draw->setFillColor('#ff0000'); // 文字色 $draw->setTextAlignment(imagick::ALIGN_CENTER); //センター寄せ $draw->annotation(140, 100, "魔法が好き!");
実行結果
サンプル9(日本語)
日本語フォントをフルパスで指定すると、日本語で文字を書くことが出来ます。
今回のサンプルにはあんずもじを使用しました。
また、文章を改行したい場合は「\n」で改行ができます。
文字の位置については以下の記事がとても詳しく書かれていて参考になります。
参考)imagickで画像に文字列を合成する際の位置 | アライドアーキテクツ エンジニアブログ
簡単な図形を描く
<?php // 図形を描く $filename = "../img/phpmagick1.jpg"; //読み込むファイル名 /* 画像の読み込み */ $image = new Imagick($filename); /* のせる四角を描く */ $draw = new ImagickDraw(); $draw->setFillColor('#ff0000'); // 色 $draw->roundRectangle(120, 70, 160, 110, 5, 5); //角丸の四角を描く /* ImagickDraw をキャンバス上に描画します */ $image->drawImage($draw); /* 画像を出力 */ header("Content-Type: image/jpeg"); //表示する画像ヘッダー echo $image; $draw->clear(); $image->clear(); ?>
実行結果
サンプル10
ImagickDrawはそれはそれで色々とやり方があるみたいです。
この辺はもう少し勉強したいですね。
上記のサンプルをまとめたzipファイルも一応用意してみました。必要な方はどうぞ。
(使用した写真やフォントファイルは入っていませんのでご注意を)
そういえば、destroy()は非推奨なのでclear()を使いましょう、とあるんですが、clear()を使ってる方をあまり見かけないんですよね。
clear()のコメントを読むと、ちょっと違うだけで殆ど重複している、らしい。公式が非推奨というからには、clear()がいいんでしょうが、どうなんですかね?
下記サイトでも色んなフィルタを使用したサンプルや、コードの書き方など紹介されていて、参考になります。
・Imagickの基本的な使い方
・PECL::Imagickを使う – m-tagの日記
・PECL::Imagick で画像リサイズ処理する場合どれ使えばいいか – (0 3 0)
・imagickで画像に文字列を合成する際の位置 | アライドアーキテクツ エンジニアブログ
PerlでImageMagickを使う方法についてもまとめた記事を書いてるんですが(こちら)、PerlとPHPで考え方は似てるけど、書き方は結構違ったりして面白いです。よかったら見比べてみてくださいね。