Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
65
Help us understand the problem. What is going on with this article?
@tokutoku393

PHPで画像のリサイズ&圧縮する方法を比較する

More than 3 years have passed since last update.

この記事は一人PHP総復習 Advent Calendar 20164日目の記事です。
いきなり内容が飛びますが、進捗がやばいので一旦書きます汗

PHPで画像をリサイズ&圧縮する際、どのライブラリを使うのがよいのか迷っていくつか調べたのでまとめておきます。
Laravelの記法などを大いに含むので、How toは参考程度にしてください。

サンプルでは保存をjpgにしてますが、元ファイルの拡張子を取得などしてください。あと本来必要なエラー処理とかも省いています。

試した環境

  • PHP7
  • Laravel5.3

php-gd

PHP拡張モジュールのGDを使う方法です。
導入はこちらの記事などを参考に。

PHPの拡張モジュールGDが動くまでの試行錯誤

How to

$h = 200; // リサイズしたい大きさを指定
$w = 200;

$file = $request->file; // 加工したいファイルを指定

// 加工前の画像の情報を取得
list($original_w, $original_h, $type) = getimagesize($file);

// 加工前のファイルをフォーマット別に読み出す(この他にも対応可能なフォーマット有り)
switch ($type) {
    case IMAGETYPE_JPEG:
        $original_image = imagecreatefromjpeg($file);
        break;
    case IMAGETYPE_PNG:
        $original_image = imagecreatefrompng($file);
        break;
    case IMAGETYPE_GIF:
        $original_image = imagecreatefromgif($file);
        break;
    default:
        throw new RuntimeException('対応していないファイル形式です。: ', $type);
}

// 新しく描画するキャンバスを作成
$canvas = imagecreatetruecolor($w, $h);
imagecopyresampled($canvas, $original_image, 0,0,0,0, $w, $h, $original_w, $original_h);

$resize_path = public_path('image/new.jpg'); // 保存先を指定

switch ($type) {
    case IMAGETYPE_JPEG:
        imagejpeg($canvas, $resize_path);
        break;
    case IMAGETYPE_PNG:
        imagepng($canvas, $resize_path, 9);
        break;
    case IMAGETYPE_GIF:
        imagegif($canvas, $resize_path);
        break;
}

// 読み出したファイルは消去
imagedestroy($original_image);
imagedestroy($canvas);

特徴

  • フォーマット別に処理を分けなくてはいけない
  • フォーマット別に圧縮率を分けやすい
  • 元画像の情報を取得しなくてはいけない
  • 基本の処理だけなら十分

Imagick

画像処理ツールImageMagickをPHPから使う拡張モジュールです。
導入はこちらの記事などを参考に。
CentOS6 上のPHPでImageMagickを動かす

How to

$w = 200; // リサイズしたい大きさを指定
$h = 200;

$file = $request->file; // 加工したいファイルを指定
$resize_path = public_path('image/new.jpg'); // 保存先を指定

// 加工するファイルを読み出し
$original_image =  new Imagick($file);
$original_image->resizeImage($w, $h, Imagick::FILTER_LANCZOS, 1);
$original_image->writeImage($resize_path);

// 読み出したイメージは消去
$original_image->destroy();

特徴

  • 対応フォーマット、できる処理はかなり多い
  • 加工後のファイルサイズが大きくなる
  • リサイズ・圧縮だけならオーバースペック感

Intervention/Image

LaravelプラグインのIntervention/Imageを使う方法です。
GDとImagickをラップしています。

導入、設定などはこちらの記事などを参考に。
Laravel5 Intervention Image 2.xを利用した画像加工

How to

$h = 200; // リサイズしたい大きさを指定
$w = 200;

$resize_path = public_path('image/new.jpg'); // 保存先を指定

$original_image = Image::make($file->path);
$original_image->resize($w, $h);

$original_image->save($resize_path);

サイズが片方だけ指定されているときは元画像の縦横比に合わせてリサイズしてくれます。

$image->resize(200, null, function ($constraint) {
    $constraint->aspectRatio();
});

特徴

  • 簡潔に記述できる
  • 圧縮率は一括指定できるが、PNG、GIFなどは未対応
  • 基本的にこれで良さそう

まとめ

Intervention/ImageはGDもImagickもラップしてくれているので、基本的にこれを選択するので良さそうです。(他にユースケースがあれば教えてください:bow:
あとIntervention/Imageでもpngとか圧縮したい場合はどうするのがベストなのでしょう・・。場合分けしてベタの関数書くしかないのかな。

65
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
tokutoku393
エンジニア兼テクニカルライター。大学は法学部。Node女学園主催。たまに電気風呂と呼ばれます。PHP/Laravel/Node.js/Milkcocoa/IoT/電子工作
dotstudio
全ての人がモノづくりを楽しむ世界を目指して活動しています。 ( https://dotstud.io ) プロトタイピングスクールの運営をしています。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
65
Help us understand the problem. What is going on with this article?