k01ken’s b10g

He110 W0r1d!

ImagicKを使って色々と画像を加工してみる

開発環境は、PHP 7.2.12 + ImageMagicK ImageMagick 7.0.7-11 Q16 x86 2017-11-23 + XAMPP Control Panel v3.2.2。

新しく画像を作成する

新しく画像を作成し、png画像のフォーマットとして、表示させます。

<?php
$image = new Imagick();
$image->newImage(100, 100, new ImagickPixel('red'));
$image->setImageFormat('png');

header('Content-type: image/png');
echo $image;
?>

実行結果
f:id:k01ken:20190125231848p:plain

画像を保存する

<?php
$image = new Imagick();
$image->newImage(100, 100, new ImagickPixel('red'));
$image->setImageFormat('png');

$image->writeImage(realpath("test.png"));
?>

と書く。writeImageのファイル名は絶対パスで指定すること。

参考リンク
http://php.net/manual/ja/imagick.writeimage.php

画像のサイズを変更する

以下のコードは、読み込んだ画像を、幅203px、高さ293pxに変換して表示している。

<?php
$image = new Imagick(realpath('test.jpg'));
$image->thumbnailImage(203,293);

header("Content-type: image/jpeg");
echo $image;
?>

thumbnailImage関数の第1引数か、第2引数を0にすると、指定した幅 or 高さに応じて自動的に、0を指定した幅 or 高さを調節してくれる。もし、高さを知りたければ、Imagick::getImageHeight関数を用いると高さを取得できる。

<?php
$image = new Imagick(realpath('test.jpg');
$image->thumbnailImage(220,0); # 例えば、高さは318pxに自動的になる

header("Content-type: image/jpeg");
echo $image;
?>

参考リンク
http://php.net/manual/ja/imagick.thumbnailimage.php
http://php.net/manual/ja/imagick.getimageheight.php
http://php.net/manual/ja/imagick.getimagewidth.php

画像の品質を変更/取得する

スクリプトのある同一ディレクトリにtest.jpgがあったとして、画像の圧縮品質を取得します。品質が高いと画像のファイルサイズが大きくなり、逆に、低いとファイルサイズが小さくなります。
値は1~100のどれかになります。

<?php
$img = new \Imagick(realpath("test.jpg"));
echo "<b>getImageCompressionQuality: </b>".$img->getImageCompressionQuality();

?>

次に画像の圧縮品質を変更してみたいと思います。
設定できる値は、1~100までです。jpeg画像だと、画像の見た目が変わりますが、png画像だと、画像の見た目は、全然変わりません。

<?php
$img = new \Imagick(realpath("test.jpg"));
$img->setImageCompressionQuality(100);
header("Content-Type: image/jpeg");
echo $img;
?>

参考リンク
https://www.php.net/manual/ja/imagick.getimagecompressionquality.php
https://www.php.net/manual/ja/imagick.setimagecompressionquality.php

画像を一部切り取って抜き出す

今回は入力した画像から、画像の中心を基準にして、正方形に切り出すプログラムを書いてみたいと思います。

<?php
$im = new Imagick(realpath('test.jpg'));
$width = $im->getImageWidth();
$height = $im->getImageHeight();

$half_width = $width / 2;
$half_height = $height / 2;

if($width > $height){
  # 縦幅の方が短い横長の画像
  $upper_half_width = $half_width - $half_height;
  $im->cropImage($height,$height, $upper_half_width,0);
}else if($width < $height){
  # 横幅の方が短い縦長の画像
  $upper_half_height = $half_height - $half_width;
  $im->cropImage($width,$width,0,$upper_half_height);
}else{
  # 最初から正方形の場合の画像
  $im->cropImage($width,$height,0,0);
}

$im->setImageFormat('jpg');

header("Content-type: image/jpg");
echo $im;

参考リンク
http://php.net/manual/ja/imagick.cropimage.php

2枚の画像を比較して差分を抽出する

下記の2枚の画像を使用します。
f:id:k01ken:20190125214822p:plain
f:id:k01ken:20190125214839p:plain

下記のプログラムでは、画像のパスは絶対パスで指定しないとエラーになる。

<?php

$image1 = new imagick("C:/xampp/htdocs/image1.png");
$image2 = new imagick("C:/xampp/htdocs/image2.png");

$result = $image1->compareImages($image2, Imagick::METRIC_MEANSQUAREERROR);
$result[0]->setImageFormat("png");

header("Content-Type: image/png");
echo $result[0];

?>

実行結果
f:id:k01ken:20190125215121p:plain

このように差分のみが赤く表示されていることが分かります。
サイトの中でデザインのどこが変更されたのか知るのにちょうどよいでしょう。


参考リンク
http://php.net/manual/ja/imagick.compareimages.php
Imagick::compareImages - ある画像を再構築された画像と比較する


画像のフォーマットを変換する

画像のフォーマットを変更するには、setImageFormat関数を用います。
例えば、以下のコードにて、読み込んだjpeg画像をpng画像に変換して表示します。

<?php

$image = new Imagick(realpath('test.jpg'));
$image->setImageFormat('png');

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

?>

参考リンク
PHP Imagick で画像フォーマット変換 – rilakkuma3xjapan's blog

画像を半透明にする

自分の環境ではなぜか、setImageOpacity関数がなかったので代替方法を探して、あったので書いておきます。

<?php
$image = new Imagick();
$image->newImage(300,300,new ImagickPixel('black'));
$image->setImageFormat('png');

$image->transparentPaintImage(new ImagickPixel('black'), 0.8,10,false);

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

?>

実行結果
f:id:k01ken:20190131232029p:plain

参考リンク
http://php.net/manual/ja/imagick.transparentpaintimage.php

画像を合成する

<?php
  $image = new Imagick();
  $image->newImage(600,600, new ImagickPixel('#cccccc'));
  $image->setImageFormat('png');

  $image2 = new Imagick();
  $image2->newImage(300,300, new ImagickPixel('#ffffff'));
  $image2->setImageFormat('png');

  $image->setImageVirtualPixelMethod(Imagick::VIRTUALPIXELMETHOD_TRANSPARENT);
  $image->setImageArtifact('compose:args', "1,0,-0.5,0.5");
  $image->compositeImage($image2, Imagick::COMPOSITE_MATHEMATICS, 0, 0); 

  header('Content-Type: image/png');
  echo $image;
?>

実行結果
f:id:k01ken:20190606220543p:plain

上に被せる画像が透過PNGだと、setImageVirtualPixelMethod,setImageArtifactを除いて、表示させると、シルエットとして表示されます。


参考リンク
https://www.php.net/manual/ja/imagick.compositeimage.php