ImageMagickでHEICをJPEGに変換する

iOS11からHEICという画像フォーマットが導入されました。

iOS11なので、2年ぐらい前ですかね。
ちょっと遅い感じがしないでもないですが、サイトの画像アップロードフォームをHEICに対応させてみたお話です。
（対応と言いつつ、HEICをJPEGに変換して扱うというものです）

ちなみに、iPhoneからinputタグでHEIFファイルをアップすると、JPEGに変換されて送られるようですので、
今回の対象はmacなどからアップされた場合とかですね。
参考：https://qiita.com/su_mi1228/items/abf4b4b51beba89a8987


# ImageMagickのサポート状況

調べたところ、ImageMagickがHEICに対応しているということで、今回はImageMagickを使うことにしました。
[ChangeLog](https://imagemagick.org/script/changelog.php) を見ると、HEICのサポート状況は下記のようです。（一部抜粋）

> 7.0.7-22 (6.9.9-34) : Add support for reading the HEIC image format
> 7.0.8-25 (6.9.10-25) : Support HEIC EXIF & XMP profiles.
> 7.0.8-46 (6.9.10-46) : Return HEIC images in the sRGB colorspace.

## インストール

まずは、お試しということでローカルのDockerを使ってみました。
Dockerfile に下記を追加してビルドします。

```dockerfile
RUN apt-get install -y imagemagick libmagickwand-dev
```

インストールされたバージョンは、こんな感じになりました。

```bash
root@f07c383510da:/var/www/html# convert --version
Version: ImageMagick 6.9.10-23 Q16 x86_64 20190101 https://imagemagick.org
Copyright: © 1999-2019 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC Modules OpenMP
Delegates (built-in): bzlib djvu fftw fontconfig freetype heic jbig jng jp2 jpeg lcms lqr ltdl lzma openexr pangocairo png tiff webp wmf x xml zlib
```

# JPEGに変換

HEICファイルがアップロードされても、そのままではブラウザで表示できません。
※[ブラウザの対応状況](https://caniuse.com/#search=heic)

なので、JPEGに変換しましょう。

```bash
$ convert upload.HEIC converted.jpg

$ ls -lh
-rwxr-xr-x 1 root root 4.3M 12月  5 20:13 convert.jpg
-rwxr-xr-x 1 root root 3.5M 12月  5 18:30 upload.HEIC
```

サクッと完了！
これで、HEICもバッチリですね。

はい。おしまい。

…だと、ちょっとネタが薄いので、以下蛇足を。

# リサイズする

当たり前ですが、HEICの方が圧縮率が高いので、
JPEGに変換するとファイルサイズがだいぶ大きくなっちゃいます。

```bash
$ ls -lh
-rwxr-xr-x 1 root root 4.3M 12月  5 20:13 convert.jpg
-rwxr-xr-x 1 root root 3.5M 12月  5 18:30 upload.HEIC
```
それに、スマホで撮ったままのサイズでは大きすぎる（そこまで大きいサイズは要らない）ので、
リサイズしてファイルサイズを抑えます。

`-resize`オプションで、1600x1600 px に収まるようにしてみます。

```bash
$ convert upload.HEIC -resize "1600x1600>" resize.jpg

$ ls -lh
-rwxr-xr-x 1 root root 784K 12月  5 20:16 resize.jpg
-rwxr-xr-x 1 root root 3.5M 12月  5 18:30 upload.HEIC
```
だいぶ小さくなりました。

# もう一歩！

だいぶ小さくなりましたが、もうちょっと小さくしてみましょう。
画質が明らかに落ちない限りは、軽い方が良いと思いますので。

こちらを参考にします。
https://developers.google.com/speed/docs/insights/OptimizeImages

```bash
$ convert upload.HEIC -sampling-factor 4:2:0 -strip \
-quality 85 -interlace JPEG -colorspace sRGB -resize "1600x1600>" optimize.jpg

$ ls -lh
-rwxr-xr-x 1 root root 469K 12月  5 20:19 optimize.jpg
-rwxr-xr-x 1 root root 3.5M 12月  5 18:30 upload.HEIC
```

おお。結構来ましたね。
最初の4.3MBから比べると、10分の1ぐらいになりました。

# あれ。画像が横向きに。。

なんか、一部の画像が横向きになっちゃいました。

さきほどの操作で、`-strip` オプションによってEXIF情報を削除したので、回転情報も消えちゃったせいでしょうか。
`-auto-orient +repage` オプションを追加して回転させてあげましょう。

※`-auto-orient`だけだと、一部回転の方向によっておかしくなるので、`+repage` も追加しましょう。
参考：https://blog.awm.jp/2016/01/06/orient/

```bash
$ convert upload.HEIC -sampling-factor 4:2:0 \
-quality 85 -interlace JPEG -colorspace sRGB \
-auto-orient +repage -strip -resize "1600x1600>" optimize.jpg
```

これでバッチリ！（のはず、たぶん、きっと）

# まとめ

ImageMagick の`convert` とか `mogrify` とか使うと、ワンライナーで書けるのが素敵ですよね。
（オプションありすぎて、分からないものいっぱいだけど…）


[:christmas_tree: FORK Advent Calendar 2019](/advent-calendar/2019/fork)
:arrow_left: 5日目 [CakePHP3：配列をあれこれするのに便利なHashクラス](/nogutea/items/c5c69236e751e878bb6e) @nogutea
:arrow_right: 7日目 @izanari さんお願いします。