Upgrade to Pro — share decks privately, control downloads, hide ads and more …

画像処理サービスを作る際の落とし穴をImageFluxではいかにして超えてきたか / ImageFlux meetup #4 (5)

Bb801526105a0ee829ba368ed78e5667?s=47 ImageFlux
August 30, 2019

画像処理サービスを作る際の落とし穴をImageFluxではいかにして超えてきたか / ImageFlux meetup #4 (5)

画像処理サービスを作る際の落とし穴をImageFluxではいかにして超えてきたか
ピクシブ株式会社
中村宇作
ImageFlux meetup #4 - 2019-08-30

Bb801526105a0ee829ba368ed78e5667?s=128

ImageFlux

August 30, 2019
Tweet

Transcript

  1. 画像処理サービスを作る際の 落とし穴を ImageFlux では いかにして越えてきたか pixiv Inc. usa 2019.8.30 ImageFlux

    meetup #4
  2. 2 自己紹介 • ピクシブ株式会社 配信技術部エンジニア ◦ つまりImageFluxの中の人 • 外ではRubyという言語の処理系を作っている ◦

    が、今日はRubyの話はしない usa Engineer Ruby Committer
  3. 3 • RailsDM 2019 (2019. 3. 23)というところで、「Webアプリケーションの開発運用で当たり 前に必要とされる画像変換の中身」という発表をした https://speakerdeck.com/unak/internal-of-the-image-processing-required-on-the-d eveloping-of-web-applications

    • 自前で画像変換しようとしたら、落とし穴がいっぱいあるよ、という内容 • 結論は「ImageMagickは偉大」 • ……なんだけど、ImageFluxはImageMagickを使っていない 前置き
  4. 4 今回の内容 • 自前で画像変換しようとしたら、落とし穴がいっぱいある • というわけで、ImageFluxでは実際にいっぱい落とし穴を踏んできた • 具体的にどんな落とし穴を踏んだのか、をご紹介

  5. 5 落とし穴①:Exif問題 • Exif = Exchangeable image file format ◦

    富士フイルムが考案、日本電子工業振興協会( JEIDA、現JEITA)で規格化 ◦ デジカメの機種ごとの差異を表現するためにメタ情報をいろいろ入れておく • GPS情報が入ってることがあって、撮影者の位置情報からプライバシーが漏れちゃうことが ある • サムネイル画像が入ってることがあって、本体の画像を加工してセンシティブ情報を消した のに、そっちにはそのまま残ってることがある
  6. 6 落とし穴①:Exif問題 • Exif情報をまるっと消しちゃえば、情報漏洩系の問題は全部解決 • ImageFluxでは、変換が行われたらExifは削除する • めでたしめでたし……?

  7. 7 落とし穴①:Exif問題 • 色空間情報(カラープロファイル) ◦ 消すと色が変わって見える!? ◦ 詳細は後述 • 回転情報(撮影時のカメラの向き)

    ◦ 消すと画像の向きが変わって見える!?
  8. 8 落とし穴①:Exif問題 • 色空間情報(カラープロファイル) ◦ 消すと色が変わって見える!? ◦ 詳細は後述 • 回転情報(撮影時のカメラの向き)

    ◦ 消すと画像の向きが変わって見える!? ◦ ImageFluxでは当初は r= 指定で各自で対処してください、というスタンス ◦ 解決策:r=auto オプションを新設して自動回転を可能に
  9. 9 落とし穴②:ICCプロファイル問題 • ICC = International Color Consotium • ICCプロファイル

    = ICCが定義した形式の色空間情報 • 主要画像ファイル形式での対応状況 ◦ JPEG:Exifの中にメタデータとして入れられる ◦ PNG:専用のチャンクとして入れられる ◦ WebP:メタデータとして入れられる ※出典:https://en.wikipedia.org/wiki/Color_space
  10. 10 落とし穴②:ICCプロファイル問題 • 色空間情報なので、なくなったら色が変わって見える(ことがある) • 画像を表示するソフトウェア側の対応状況如何なので、プロファイルがあるせいでソフトウェ アによっては色が違って見えることがある ◦ 以前はブラウザごとに対応状況にばらつきがあってつらかった ◦

    最近のモダンなブラウザはだいたい対応しているので、そういう前提にしてもよくなっ た感じはある
  11. 11 落とし穴②:ICCプロファイル問題 • JPEGの場合、Exifをまるっと消したら一緒に消える • GIF(ICCプロファイル非対応なフォーマット)に変換したらどうなる? ◦ GIFは256色しか使えないからそこまで問題にはならないとはいえ ……

  12. 12 落とし穴②:ICCプロファイル問題 • JPEGの場合、Exifをまるっと消したら一緒に消える • GIF(ICCプロファイル非対応なフォーマット)に変換したらどうなる? ◦ GIFは256色しか使えないからそこまで問題にはならないとはいえ …… •

    解決策1:出力はsRGBと決めつけて、入力時に存在した ICCプロファイルからsRGBに色を 変換しちゃう • 解決策2:GIFについては解決策1、それ以外は ICCプロファイルを覚えておいて、変換後に 再埋め込みする
  13. 13 落とし穴②:ICCプロファイル問題 • オーバーレイ合成機能(複数の画像を重ね合わせ合成する機能) ◦ 入力画像ごとにICCプロファイルの中身が違ったらどうする?

  14. 14 落とし穴②:ICCプロファイル問題 • オーバーレイ合成機能(複数の画像を重ね合わせ合成する機能) ◦ 入力画像ごとにICCプロファイルの中身が違ったらどうする? ◦ 解決策:オーバーレイ画像側の色空間を、ベース画像側の色空間に変換する

  15. 15 落とし穴②:ICCプロファイル問題 • オーバーレイ合成機能(複数の画像を重ね合わせ合成する機能) ◦ 入力画像ごとにICCプロファイルの中身が違ったらどうする? ◦ 解決策:オーバーレイ画像側の色空間を、ベース画像側の色空間に変換する ▪ 「なんか、変換エラーになる画像があるんですけど!?」

  16. 16 落とし穴②:ICCプロファイル問題 • オーバーレイ合成機能(複数の画像を重ね合わせ合成する機能) ◦ 入力画像ごとにICCプロファイルの中身が違ったらどうする? ◦ 解決策:オーバーレイ画像側の色空間を、ベース画像側の色空間に変換する ▪ 「なんか、変換エラーになる画像があるんですけど!?」

    ▪ 稀に非互換なICCプロファイルの組み合わせが存在する ▪ 解決策:そういう場合は諦めて両方の画像を sRGBに変換する
  17. 17 落とし穴③:透過部背景色指定問題 • おさらい:「透過」とは? ◦ 文字通り色が透けること ◦ GIFだと「透過色」を指定できて、そのパレット番号が指定されたピクセルは透明なも のとして扱われる ◦

    PNGやWebPにはアルファチャネルというものが存在し、ピクセルごとに「不透過度」 によってどの程度透けているか(というか透けていないか)を指定できる ◦ JPEGには……ない(一切透けない)
  18. 18 落とし穴③:透過部背景色指定問題 • PNG等からJPEGに変換するとき、透過をどう扱うか? ◦ ImageFluxでは背景色を指定できて、元ピクセルの透過度に応じて、ピクセルの色と 背景色を合成する ◦ ごくごく平凡な対応

  19. 19 落とし穴③:透過部背景色指定問題 • PNG等からJPEGに変換するとき、透過をどう扱うか? ◦ ImageFluxでは背景色を指定できて、元ピクセルの透過度に応じて、ピクセルの色と 背景色を合成する ◦ ごくごく平凡な対応 ◦

    「なんか灰色の線が出るんですけど!?」
  20. 20 落とし穴③:透過部背景色指定問題 • ImageFluxではリサイズしてから背景色との合成をしていた • 完全透過ピクセルとそうでないピクセルとがリサイズで融合されると、それらのピクセルの 間の色・間の透過度のピクセルが生成される • 完全透過ピクセルは黒として扱っていたが、そうでない方のピクセルが黒以外(例えば白) だったら、灰色で少し透過しているピクセルが生成される

    • そこに背景色(例えば白)を合成しても 少し灰色が残る
  21. 21 落とし穴③:透過部背景色指定問題 • ImageFluxではリサイズしてから背景色との合成をしていた • 完全透過ピクセルとそうでないピクセルとがリサイズで融合されると、それらのピクセルの 間の色・間の透過度のピクセルが生成される • 完全透過ピクセルは黒として扱っていたが、そうでない方のピクセルが黒以外(例えば白) だったら、灰色で少し透過しているピクセルが生成される

    • そこに背景色(例えば白)を合成しても少し灰色が残る • 解決策:出力フォーマットがJPEGなら、リサイズ前に背景色と合成しておく
  22. 22 落とし穴④:クロップ時内部変換問題 • ImageFluxにおけるクロップとは? ◦ 入力画像を指定されたサイズを満たすように拡大縮小し、縦横いずれかがはみ出す 場合は、はみ出した部分を切り捨てる機能 ◦ 具体的には a=2

    のこと
  23. 23 落とし穴④:クロップ時内部変換問題 • ImageFluxにおけるクロップとは? ◦ 入力画像を指定されたサイズを満たすように拡大縮小し、縦横いずれかがはみ出す 場合は、はみ出した部分を切り捨てる機能 ◦ 具体的には a=2

    のこと • 「なんかメモリ食いつぶしちゃうんですけど!?」
  24. 24 落とし穴④:クロップ時内部変換問題 • 入力画像のサイズ: 10000px × 1px • 出力指定サイズ:300px ×

    300px
  25. 25 落とし穴④:クロップ時内部変換問題 • 入力画像のサイズ: 10000px × 1px • 出力指定サイズ:300px ×

    300px • 元画像を指定されたサイズを満たすように拡大縮小
  26. 26 落とし穴④:クロップ時内部変換問題 • 入力画像のサイズ: 10000px × 1px • 出力指定サイズ:300px ×

    300px • 横は既に満たしているので後回し • 縦は入力画像の 1px で 300px を満たさないといけないので、300倍の拡大
  27. 27 落とし穴④:クロップ時内部変換問題 • 入力画像のサイズ: 10000px × 1px • 出力指定サイズ:300px ×

    300px • 横は既に満たしているので後回し • 縦は入力画像の 1px で 300px を満たさないといけないので、300倍の拡大 • よって、横は 10000px の300倍になるので、3000000px • 3000000px × 300px の画像を内部的に生成してから、これを 300px × 300px に切り抜く ことになる
  28. 28 落とし穴④:クロップ時内部変換問題 • 解決策:切り抜いた結果の画像が、元の画像のどの部分に相当するかを事前に算出し、そ の部分だけを抜き出してから拡大縮小する ◦ 倍率によっては、必ずしも元画像のピクセル境界に一致するわけではないので、 ちょっと大きめに切り抜くとかの細かい工夫は必要

  29. 29 その他の落とし穴 • オーバーレイ合成機能時に、入力画像の内部形式が全然違う場合どうする? ◦ YCbCrとRGBとか、RGBとGrayscaleとか • パレット形式の画像の拡大縮小時にピクセル融合が発生した場合、元画像になかった色が 発生する ◦

    パレット形式をやめる? ◦ 元画像に存在した色しか使わない? ◦ パレットを作り直して他の色を変えちゃう?
  30. 30 その他の落とし穴 • 他にも無限に落とし穴が存在する ◦ しかも、 必ずしも正解があるとは限らない ◦ 全ては要件次第 •

    性能の問題も考慮する必要がある ◦ 速度 ◦ メモリ消費量 ◦ 出力画像品質
  31. 31 まとめ • ImageFluxではいろいろ頑張って画像変換をやっています! • 使っていて何か問題に気づいたらお気軽にお問い合わせください • まだ使ってない方は https://www.sakura.ad.jp/services/imageflux/

  32. ご清聴ありがとうございました 32