golangで画像生成

雨の日が多く蒸し暑い日々で、外に出たくないと思うことが増えてきましたね。 最近、ブログを書いておらず技術的ブログを書く感覚が相当鈍っていますが、頑張って書きます。

今回はgolangで画像生成をした際に直面した問題や課題、改善点などをつらつらと書いていこうと思います。                                                                

なぜgolangで画像処理なのか

f:id:poccariswet:20200705160056p:plain

golangで画像生成する利点はいくつかあると思います。

  • サーバー側で画像を生成したい

  • 標準パッケージがあり、他にもリッチな画像処理のライブラリがある。 (特にgolangの標準パッケージはピクセル単位で画像加工ができ、有用だと思います。)

問題点、課題

ただ、golangで画像処理をする際にしばしば、問題にぶち当たりました。

fontの対応がすくない、 fontをロードするライブラリのメンテがされていない

ということです。

実際に、実装していく中で、画像の上に文字を描写する必要がありました。 golangのfontパッケージを利用し、fontをロードすると

 invalid TrueType format: bad TTF version

のように、golangのfontパッケージは True Type Fontしか対応していないのです。

そのため、くないと思うことが増えてきましたね。 最近、ブログを書いておらず技術的ブログを書く感覚が相当鈍っていますが、頑張って書きます。

今回はgolangで画像生成をした際に直面した問題や課題、改善策などをつらつらと書いていこうと思います。                                                                               

なぜgolangで画像処理なのか

golangで画像生成する利点はいくつかあると思います。

  • サーバー側で画像を生成したい

  • 標準パッケージがあり、他にもリッチな画像処理のライブラリがあった。

特にgolangの標準パッケージはピクセル単位で画像加工ができ、有用だと思います。

問題点、課題

ただ、golangで画像処理をする際にしばしば、問題にぶち当たりました。

fontの対応がすくない、 fontをロードするライブラリのメンテがされていない

ということです。

実際に、実装していく中で、画像の上に文字を描写する必要がありました。 golangのfontパッケージを利用し、fontをロードすると

 invalid TrueType format: bad TTF version

のように、golangのfontパッケージは True Type Fontしか対応していないのです。

そのため、複数の言語対応や絵文字などを使う際に、unicodeの範囲の正規表現を設け、判断しその、unicodeにあった true type fontを適用しなければなりません。


次に自分が直面した問題は、これです。

ハードコードする部分が多くなる

下記に張ったリンクを見るとわかるのですが、 blog.golang.org

どこに、なにを、どれぐらいの範囲でというパラメーターの数々を自分で考え、計算し数値に置き換え準備しなければなりません。 これは、とても根気がいり、工数のかかる作業です。

...
        tableX = append(tableX, 40)
        tableX = append(tableX, 560)
        tableX = append(tableX, 1080)
        tableX = append(tableX, 1600)

        var letterMoreY []LetterMoreY
        letterMoreY = append(letterMoreY, LetterMoreY{
            UpperY:  110,
            BottomY: 170,
        })
        letterMoreY = append(letterMoreY, LetterMoreY{
            UpperY:  343,
            BottomY: 403,
        })
        letterMoreY = append(letterMoreY, LetterMoreY{
            UpperY:  576,
            BottomY: 636,
        })
...

実際に自分もコードを書く際にとてもハードコードする量が増えてしまい、可読性、汎用性のあるコードとは言えないものになってしまいました。

改善策

上で示したように、golangでリッチな画像を作ったり、様々なfontを使用することは現時点では厳しいものかつ工数がかなりかかるものだということわかりました。


ただ、この問題を改善する方法として

headless browserによる画像生成
があげられます。

headless browserによる画像生成利用方法や具体的な実装方法に関しては、

note.com

timakinさんが解説してくださっているので是非、ご一読ください。


簡単に headless browserについて説明すると、chromeなどのbrowserをUIなしに扱えるものです。特に、GUI を持つ必要のない自動テスト環境やサーバー環境で優遇されます。


browserが提供する、フォント群や、web frontの技術(css)を用いて、画像や文字の配置ができるのでgolangで実装した方法よりも楽になります。

ただ、headless browserを使うと、起動時間がかかることで生成時間が伸びたり、サーバーへの負荷が懸念されます。
(簡単な画像生成やfontに依存しない場合は、imageパッケージを使用してもよいかもしれませんね)

最後に

自分は、実装するまで、golangの画像処理にこのような課題があることを知りませんでした。

headless browserを使うことで、golangの課題であるフォント問題や、ハードコード問題を解決できるので、時間がある際に試してみようと思います。