🎨

[Go]`image.Decode()`の代替メソッドを作る

に公開

Goのimage.Decode()多くの画像に対してエラーを起こします。例として、

unexpected EOF
invalid JPEG format: short Huffman data
unsupported JPEG feature: luma/chroma subsampling ratio

しかもこの問題、10年以上に渡って解決されていません。Goの公式レポジトリのIssueにはこうあります。

As long as the attitude prevails of "we made a booboo by assuming nobody will run into this and now we fear fixing it because of backward compatibility" ... with that attitude, it will never get fixed. This issue is known for 13 years, ...
(抄訳)
「問題が起きないとは言い切れない」と後方互換性を維持する姿勢が蔓延している限り、この問題は決して修正されないだろう。この問題は13年に渡って知られているが……(2024年の投稿)

同じIssueにImageMagickという(Goとは関係ない)ソフトで画像を変換するという解決法が書かれています。ただしこの方法は遅いので、Go組み込みのimage.Decode()が失敗した場合だけ実行する方法を取ります。
以下のページに詳しく解説されています。
https://zenn.dev/aeon_mall/articles/b54d3abad707d8
このようにmagick外部コマンドを実行する形になります。

params := []string{
		"-",                         //Stdin image
		"-sampling-factor", "4:4:4", //downsize Chroma Sub-sampling
		"-", //Stdout image
	}
cmd := exec.Command("magick", params...)

モジュール化したので、以下の手順で使えます。
1.ImageMagickをインストール: https://imagemagick.org/script/download.php
2. 以下のコマンドでモジュールをインストール

go get github.com/lamrongol/go-imagemagick-decode

後はimage.Decode()と書いていた箇所をmagick.Decode()に置き換えるだけです。
https://github.com/lamrongol/go-imagemagick-decode

Discussion