Slide 1

Slide 1 text

logica X: @logica0419 GitHub: @logica0419 Pure Goで アニメーションGIFの リサイズを実装する logica X: @logica0419 GitHub: @logica0419

Slide 2

Slide 2 text

自己紹介 ● logica (ろじか) ● 千葉工業大学 情報科学部情報ネットワーク学科 ● ネットワークコンテンツ研究会 所属 ○ 数人の自宅サーバーをVPNで繋いでクラウド基盤 作ろうとしてます ● (元 東京工業大学) ● (元 traP)

Slide 3

Slide 3 text

このLTは今年の GopherCon 及び Go Conference に 応募して どちらも不採択となった プロポーザルを 超超圧縮した バージョンです

Slide 4

Slide 4 text

アニメーションGIFの リサイズ (拡縮) を アプリに組み込んだことが ある人?

Slide 5

Slide 5 text

アニメーションGIFの リサイズ (拡縮) を 仕事で使ったことが ある人?

Slide 6

Slide 6 text

プロポーザルが不採択に なった理由が わかりましたね! 正直あまりに需要が少なかったと思う

Slide 7

Slide 7 text

なぜアニメーションGIFリサイズなのか ● https://github.com/traPtitech/traQ ○ 昨年度までメンテしてたプライベートSNS ● アニメーション付きアイコン・スタンプの作成機能 ○ 容量削減のため アップロード された画像を リサイズする 必要があった

Slide 8

Slide 8 text

GoでのGIFリサイズの現状 ● Pure Go実装だと、まともな情報が少ない ○ 出回っている情報だけでは特定タイプのGIFしか 正確に処理できない ■ GIFの仕様が複雑なせい ■ Goのライブラリでデコードされた形が ちょっと扱いづらいせい ○ サードパーティーライブラリも似たような感じ

Slide 9

Slide 9 text

GoでのGIFリサイズの現状 ● ImageMagickや、Cライブラリのラッパーライブラリ ○ 割と主流 ○ かなり正確に処理できる ○ 容量がデカい ■ 画像処理全般が一緒になっている事が多い ○ Distrolessイメージに積みづらい ■ Distroless化に挑戦してみたかったのでネック

Slide 10

Slide 10 text

頑張ってPure Goでまともな GIFのリサイズを実装したい! 出来れば 標準 + golang.org/x ライブラリ だけでやりたい

Slide 11

Slide 11 text

GoでGIFを扱う ● 標準ライブラリ image/gif ○ https://pkg.go.dev/image/gif ● gif.DecodeAll() して、*gif.GIF 構造体で扱える type GIF struct { Image []*image.Paletted ← 1枚1枚のフレーム Delay []int LoopCount int Disposal []byte ← 激ヤバポイント① Config image.Config ← GIFのメタデータ類 BackgroundIndex byte ← 激ヤバポイント② }

Slide 12

Slide 12 text

GIFリサイズの沼 ● 大抵の記事は、ここから Image 配列の中のフレームを 1つずつリサイズするところまでしか書いてない ● それだけでは対応できない部分がたくさんある! 今回は紹介したかった沼ポイントの うち1つを抜粋して説明します

Slide 13

Slide 13 text

差分最適化

Slide 14

Slide 14 text

GIFがあります ● 初音ミクですね ● 瞬きしてますね

Slide 15

Slide 15 text

リサイズすると ● 違いが分かりやすいよう 「同じサイズにリサイズ」 してみた

Slide 16

Slide 16 text

Long_Miku.gif になってしまった

Slide 17

Slide 17 text

なぜ縦長になってしまったのか ● 差分最適化 ○ アニメーションで動かない部分は 次以降のフレームに含めない手法 ○ 上から重ねて描画していく ● 例えば今回のだと、各フレームのデータは ○ 1枚目: 全体の画像 ○ 2枚目以降: 赤枠部分の画像とその位置情報のみ ● 情報量を削減できる

Slide 18

Slide 18 text

なぜ縦長になってしまったのか ● 全てのフレームを指定されたサイズに合わせる実装だと ○ 1枚目: 問題なし ○ 2枚目以降:  引き伸ば されてしまう

Slide 19

Slide 19 text

という理由でLongになってしまう

Slide 20

Slide 20 text

解決策 ● 全フレームでリサイズ後のサイズを計算する ○ 指定されたリサイズ後のサイズと 元々のGIFのサイズから、拡縮比率を計算 ○ それぞれのフレームの大きさに比率をかけて 適切なリサイズ後のサイズを計算する

Slide 21

Slide 21 text

すなわち ● 全フレームでリサイズ後のサイズを計算する実装だと ○ 1枚目: 問題なし ○ 2枚目以降: 問題なし

Slide 22

Slide 22 text

解決! Happy!!!

Slide 23

Slide 23 text

まだ道のりは長い ● 透明ピクセルに起因する謎ノイズ ● Disposalというめんどくさい仕様 ● 背景色がきちんと設定されていないGIF (!!!???????) ● リサイジングの高速化 ○ 並列処理 ○ リサイズする関数の入れ替えを可能に ● リサイズ時のオプションをリッチに

Slide 24

Slide 24 text

最終的に、これらをまとめて github.com/logica0419/resigif を作りました

Slide 25

Slide 25 text

ありがとう ございました GIFをリサイズする際は是非お使いください