PHPで画像サイズを変更してみた

Linuxのconvertコマンドを知らず、
convertコマンド1行で出来ることを苦戦しながらPHPで実装したので、
せっかくなのでメモとして残します。

業務での目的としては1000x1000の画像を、
上下に余白をつけて1000x1200にするというようなものでしたが、
Qiita用に少し修正して上下左右に余白をつける例にしてみました。
# 余白をつける方針
画像にどう余白をつけるかというと、
余白用の画像を作成して、その上に元の画像を重ねるという方針です。
# サンプル
ファイル名や余白の幅は固定になっているので、
参考にする場合は適宜修正していただければと思います。

```ruby:resizeImage.php
<?php

// ファイルパスは固定
const IMAGE_PATH = __DIR__ . '/images/target.jpeg';
const RESIZE_WIDTH = 20;
const RESIZE_HEIGHT = 20;
const RESIZE_FILE_NAME = "after";

// 元の画像名を指定してサイズを取得
list($width, $height) = getimagesize(IMAGE_PATH);

// リサイズ後の画像の幅、高さを計算
$afterWidth = $width + (RESIZE_WIDTH * 2);
$afterHeight = $height + (RESIZE_HEIGHT * 2);

// サイズを指定して余白画像を作成
$backgroundImg = imagecreatetruecolor($afterWidth, $afterHeight);
$backgroundColor = imagecolorallocate($backgroundImg, 255, 255, 255);

// 白の背景を作成
imagefilledrectangle(
    $backgroundImg,
    0,
    0,
    $afterWidth,
    $afterHeight,
    $backgroundColor
);

//画像オブジェクトを返却
$baseImage = @imagecreatefromjpeg(IMAGE_PATH);

// 余白画像と元画像を合成
imagecopy(
    $backgroundImg,
    $baseImage,
    RESIZE_WIDTH,
    RESIZE_HEIGHT,
    0,
    0,
    $width,
    $height
);

// コピーした画像を出力する
imagejpeg($backgroundImg , RESIZE_FILE_NAME . '.jpg');


```
# プログラムの説明
## 元画像のサイズを取得
```
list($width, $height) = getimagesize(IMAGE_PATH);
```
[list](https://www.php.net/manual/ja/function.list.php)を使って、[getimagesize](https://www.php.net/manual/ja/function.getimagesize.php)の返却値から画像の幅と高さを取得してます。
元画像のサイズが固定なら不要ですが、今回は元画像のサイズによらず上下に余白をつけるだけなので、
元画像のサイズを取得します。

ちなみにgetimagesize()は画像の形式なども返却されるようです。
## 余白画像を作成
```
$backgroundImg = imagecreatetruecolor($afterWidth, $afterHeight);
```
[imagecreatetruecolor](https://www.php.net/manual/ja/function.imagecreatetruecolor.php)で余白画像を作成します。
パラメータは幅と高さです。
余白の画像なので元画像より幅と高さを大きくします。
この段階だと背景色は黒になります。
また返却値は画像オブジェクト(GDImage クラスのインスタンス)です。

## 余白画像を白にする
```
$backgroundColor = imagecolorallocate($backgroundImg, 255, 255, 255);
```
余白画像作成時点で色の指定が出来ればいいのですが、
最初からは指定が出来ないようだったので、
まずは[imagecolorallocate](https://www.php.net/manual/ja/function.imagecolorallocate.php)で `A color identifier`(色のID)を取得します。

1つ目のパラメータは先ほど作成した画像オブジェクトです。
2, 3, 4は[RGB](https://www.rapidtables.com/web/color/white-color.html)で指定すればいいようなので、
白以外にしたい場合はここを変更します。

ちなみに、この時点では色のIDを取得しただけなので余白画像は白くなってません。
最初、ここで苦戦しました。
「白くならない、、」と。ちゃんとドキュメントは読んだ方がいいですね。

```
// 白の背景を作成
imagefilledrectangle(
    $backgroundImg,
    0,
    0,
    $afterWidth,
    $afterHeight,
    $backgroundColor
);
```
次に、[imagefilledrectangle](https://www.php.net/manual/ja/function.imagefilledrectangle.php)で画像に色をつけます。
一応説明すると、
1つ目のパラメータで色をつけたい画像オブジェクトを指定。
2, 3つ目のパラメータで画像左上のx,y座標。
4, 5つ目のパラメータで画像右下のx,y座標。
6つ目のパラメータで色のIDを指定。（ドキュメント的には「imagecolorallocate() で作成された色識別子。」）
やっと背景画像が白くなりました。
## 余白画像に元画像を合成
```
//画像オブジェクトを返却
$baseImage = @imagecreatefromjpeg(IMAGE_PATH);
// 余白画像と元画像を合成
imagecopy(
    $backgroundImg,
    $baseImage,
    RESIZE_WIDTH,
    RESIZE_HEIGHT,
    0,
    0,
    $width,
    $height
);
```
[imagecopy](https://www.php.net/manual/ja/function.imagecopy.php)で余白の上に元画像をコピーします。
パラメータが多くてややこしいですが、やりたいことさえわかっていれば簡単かと思います。
1つ目のパラメータに背景の画像オブジェクト、2つ目に元画像の画像オブジェクトを指定します。
余白を作る上で大事なのが3, 4つ目のパラメータで、
ここで元画像のコピーの位置をずらすことで余白になります。
## 画像ファイルに出力
```
// コピーした画像を出力する
imagejpeg($backgroundImg , RESIZE_FILE_NAME . '.jpg');
```
[imagejpeg](https://www.php.net/manual/ja/function.imagejpeg.php)でjpegに画像ファイルを出力します。
ここでやっと画像が作成されます。

改良の余地はたくさんありそうですが、
普段、PHPで画像の操作をしていない私のような方の参考になればと思います。