学習用の掲示板サイトをAWSに移行してから、稼働料金にヒヤヒヤしながら過ごす日々を送っています。
1年間は無料利用枠を使えることができるため暫くの間は問題ないのですが(24年9月時点で月0.57ドル。8月はドメイン移行等に料金がかかり月28ドルほど)、無料利用枠の終了する来年以降は月10ドル以上のコストがかかってしまいそうで怖いです。
所持している掲示板サイトの機能に画像アップロード機能があるのですが、実装が面倒だったので今までリサイズせずアップされた画像をオリジナルサイズのまま格納、表示していました(ひどいですね)。ストレージの圧迫も今後料金が嵩む原因となり得ますので、自分のサイトにIntervention Image
ライブラリを導入して画像をリサイズして格納できるようにしてみました。
Intervention Imageについて
画像をリサイズすることができるPHPのライブラリで、Laravel
ではcomposer
で導入可能です。
導入する
composer.json
のあるディレクトリで、以下を実行して導入できます。
composer require intervention/image
# composer.json
"require": {
"php": "^8.2",
"doctrine/dbal": "^3.0",
"intervention/image": "^3.8", ←導入できた
"laravel/framework": "^11.0",
"laravel/tinker": "^2.0",
"laravel/ui": "^4.0"
},
エラーが発生する場合はPHPのバージョン等が合っていなかったりするケースかと思います。
今回は laravel11.x
にIntervention Image
v3.8
を導入してみました。v2.x
と文法が結構変わっているっぽいので何かの参考になればと思います。とはいっても下記ドキュメントに記載されている内容の通りですが。
ImageMagickを導入する
Intervention Image
ライブラリを使うために、まずImageMagick(Imagick)
を環境にインストールする必要があります。
macで開発しているならmacに、Dockerで開発しているならPHPが導入されているコンテナに、EC2で稼働しているサイトならインスタンスに導入が必要です。自分の場合はDockerとEC2(Amazon Linux 2023)に導入しました。
Dockerの場合
自分の場合はphp8.2
のコンテナをDockerfile
で呼ばせてもらっているので、こんな感じです。
FROM php:8.2-fpm
COPY php.ini /usr/local/etc/php/
RUN apt-get update \
&& apt-get install -y zlib1g-dev mariadb-client vim libzip-dev libmagickwand-dev --no-install-recommends \
&& docker-php-ext-install zip pdo_mysql \
&& pecl install imagick \
&& docker-php-ext-enable imagick
本記事に関連のないライブラリの導入記述もあるので改めてImageMagick
に関する記述だけ起こすと下記の通りです。
FROM php:8.2-fpm
RUN apt-get update \
&& apt-get install -y libmagickwand-dev --no-install-recommends \
&& pecl install imagick \
&& docker-php-ext-enable imagick
依存ライブラリなどをインストールし、docker-php-ext-enable
でimagick
を有効化します。
その後コンテナを再ビルドして、上記設定をコンテナに反映してください。
Amazon Linux 2023の場合
ssh
でインスタンスでログインしたのち、同じように関連ライブラリを導入します。
# ライブラリ導入
sudo dnf install ImageMagick ImageMagick-devel
sudo dnf install php-cli php-devel php-pear # いらない場合もある
sudo dnf install gcc # いらない場合もある
# imagickの拡張をインストール
# https://www.php.net/manual/ja/install.pecl.intro.php
sudo pecl install imagick
"please provide the prefix of imagemagick installation autodetect"
という表示で止まりますが、Enter
を押下すると先に進めます。
# php.iniにimagick拡張を読み込むため、ファイルに記述し有効化させる
echo "extension=imagick.so" | sudo tee /etc/php.d/20-imagick.ini
# 使用しているwebサーバ(自分の場合はnginx)とphp-fpmにrestart
sudo systemctl restart php-fpm
sudo systemctl restart nginx
こちらで導入ができました。以下はCLI上で行うことができる軽い導入確認方法です。
# 確認その1
php --ini | grep imagick
/etc/php.d/20-imagick.ini, ←先ほどteeで作成したiniファイルがあること確認
# 確認その2
php -r 'phpinfo();' | grep imagick
# phpinfoの情報にimagickに関する記述があれば導入できている。
/etc/php.d/20-imagick.ini,
imagick
imagick module => enabled
imagick module version => 3.7.0
imagick classes => Imagick, ImagickDraw, ImagickPixel, ImagickPixelIterator, ImagickKernel
imagick.allow_zero_dimension_images => 0 => 0
imagick.locale_fix => 0 => 0
imagick.progress_monitor => 0 => 0
imagick.set_single_thread => 1 => 1
imagick.shutdown_sleep_count => 10 => 10
imagick.skip_version_check => 0 => 0
使ってみる
blade
で作成したフォームから画像が送られてきた場合のリサイズ処理を想定しています。フォームの作成方法などは今回省略し、Controller
側の記述のみ記載します。
使いたいController
ファイルにuse
でインポートします。
// 画像リサイズに使用する
use Intervention\Image\ImageManager;
use Intervention\Image\Drivers\Imagick\Driver;
その後は、以下のような形で使用可能です。
class PostController extends Controller
{
public function store(StorePostRequest $request)
{
// アップロードされた画像ファイルに対して処理を行う
if ($request->hasFile('picture')) {
$picture = $request->file('picture');
// 画像リサイズ
$manager = new ImageManager(new Driver()); // Imagemanagerインスタンス作成
$resized_picture = $manager
->read($picture->getPathname()) // 操作する画像ファイルの読み込み
->scaleDown(width: 600); // 横幅600pxにリサイズ
$picture_name = uniqid('pic_') . '.' . $request->file('picture')->guessExtension();
$resized_picture->save(storage_path('app/public/uploads/' . $picture_name));
}
ImageManager
インスタンスを作成し、read()
で読み込み、希望の画像処理に対応するメソッドを呼び出すという流れが基本です。これだけでリサイズ処理を実装することができました。
なお、v2.x
ではread()
メソッドの代わりとしてmake()
で画像を読み込んでいたようですが、v3.8
では使用することができません。結構変わっているようなので文法エラーに気をつけて作業しましょう。下記ドキュメントにメソッド一覧が記載されています。
今回自分はscaleDown()
を使わせてもらいました。scale()
と違ってリサイズ後に画像の元サイズを超えることはありません。100*100
の画像があったとして、scale(width: 600)
とすると600*600
の画像となりサイズが大きくなってしまうのですが、scaleDown()
ではその現象を防ぐことができます。
終わりに
Intervention Image
を使用すると手軽にリサイズ処理の実装ができました。
実は4年くらい前にプログラムの学習始めたてだった頃、インフラ部分に関する知識が全く無くImageMagick
の導入で心が折れた結果、バニラのPHPでリサイズ機能(笑)を自作したことがあります。
この作業がありえないくらい大変だった記憶があり、結果リサイズ機能を導入することに対して今までずっと腰が重かったのですが、ライブラリを使うと非常に楽で良かったです。また4年前は挫折したImageMagick
ですが、現在は環境に導入することができるようになっていたので少しは成長できたのかもしれません。
備考
自分のサイトに導入した際のプルリクエスト
参考にした記事
ImageMagickには不安要素もあるようなので、お気をつけください。
コメント