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

Internal of the image processing required on th...

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for usa usa
March 23, 2019

Internal of the image processing required on the developing of web applications

Webアプリケーションの開発にあたっては、現代においては大量の画像を扱わないといけないことは明らかである。その際には、サイズ変換・フォーマット変換・転送量削減といったあたりは当然に必要となる。単純に見えて実は落とし穴がいっぱいなこうした画像変換の中身について、技術的側面から説明する(※デザインの話はしません)

Avatar for usa

usa

March 23, 2019
Tweet

More Decks by usa

Other Decks in Programming

Transcript

  1. 2 自己紹介 • CRubyのコミッタ (安定版リリースマネージャ ・Windows版担当) • www.ruby-lang.orgの記事をいっぱい書いてる人 (全体の1/4くらい) •

    配信技術部 = 画像とか動画とかそのものを取り 扱ってインターネットに流すための諸々をやるところ • 仕事では普段はだいたいGoで書いている • 仕事以外では普段はだいたいCで書いている 配信技術部エンジニア
  2. 7 「 アプリ」は だけじゃないよ 7 • 実質ブラウザっていうスマートフォン用アプリ ◦ 皆さん作ってますよね? •

    「実質ブラウザ」じゃないにしても、コンテンツを HTTP(S)で随時拾ってくる系のやつ ◦ ゲームとか ◦ ショッピングサービス(EC)
  3. 10 :手元で必要な加工をしてアップロード デプロイ 10 • 心温まる手作業…… • めんどくさい • だいたい定型作業なので頻度が増えてきたらスクリプトである程度自動化

    ◦ あれ、自動化してるのになんで人間が手で叩いてるんだっけ ……? • そもそも、画像をアップロードするのが自分 (開発・運用者)じゃない場合がある ◦ ユーザーがアップロードするやつとか
  4. 11 :アップロード時にサーバサイドで加工 11 • 楽ちん! • 配信サーバと共有すると運用上いろいろ不安がなくもない ◦ 負荷(特にメモリ)がアップロード時のみ高まる ▪

    金で解決してもいいけど、普段は完全にオーバースペックで無駄 ◦ き、脆弱性…… • 分離した画像変換サーバを用意すればいくらかマシにはなる
  5. 20 画像ファイルの読み込み import( "image" "os" ) func LoadImage(path string) (image.Image,

    error) { file, err := os.Open(path) if err != nil { return nil, err } defer file.Close() img, _, err := image.Decode(file) return img, err }
  6. 21 画像ファイルの書き出し func SaveImage(img image.Image, path string) error { file,

    err := os.Create(path) if err != nil { return err } defer file.Close() switch filepath.Ext(path) { case ".jpg", ".jpeg": return jpeg.Encode(file, img, &jpeg.Options{Quality: 100}) case ".png": return png.Encode(file, img) case ".gif": return gif.Encode(file, img, &gif.Options{}) } return fmt.Errorf("unsupported file: %s", path) }
  7. • AはAlpha channel(透過度、というか、透過してない度 ) • Nは何? • みんながぱっと想像する単純な R, G,

    B, Aの各値を持つのはNRGBA ◦ RGBAはR, G, BにAlphaの値を掛けたものが入っている(alpha-premultiplied) ◦ なので、NRGBAは “Non-alpha-premultiplied RGBA” のこと • どうせ表示する時は掛け算しないといけないので、最初から掛けておくという発想 (クライ アント側に優しい……のかなぁ……) 24 と
  8. • 0 (透過100%)をR, G, Bに掛けると、全部 0 になる ◦ つまり色情報が消える •

    リサイズ時に問題が起きる ◦ 隣のピクセルの色を見て色を混ぜたりする ◦ 透過ピクセルの色は常に「黒」 • color.Color 型の共通インターフェースは RGBA() ◦ 実際のデータがNRGBAであっても直接メンバを見ない限り RGBAになる 25 の落とし穴
  9. • 知ってる? ◦ Y:輝度 ◦ Cb:青色差 ◦ Cr:赤色差 • 人間の視覚は輝度の変化には敏感だがそれと比べれば色差には鈍感

    ◦ なので輝度情報と比べて色差の情報は間引ける • RGBとは簡単な計算式で相互変換可能 27
  10. • 印刷用 • Cyan, Magenta, Yellow, K...??? ◦ blacK? Kuro?

    Karbon? Key plate? • 入稿用データとかでは普通に存在する • これも加工時にはRGBを経由しない方が無難 29
  11. • いろんなメタ情報が入ってる ◦ 撮影場所のGPSの情報とかが入っていて問題になりがち • Go標準の image/jpeg パッケージはExifを取り扱わない ◦ ので読んで書いたら消える。ラッキー!?

    • Orientation情報:回転 ◦ 消したら「画像の向きが変わった!」とか言われる • Exif読み込んで解釈してGPS情報だけ消すとか地獄 30 問題
  12. • ICC:International Color Consotium • 追加の色情報(色空間の補正) • 最近のだいたいのブラウザはサポートしている • ブラウザと画像処理専門ソフト(Photoshopとか)以外はサポートしてない

    • Goの image パッケージも未サポート ◦ 読んで書いたら消える ◦ つまり、色が変わって見える 31 プロファイル問題 https://en.wikipedia.org/wiki/Color_space より
  13. • ここまで挙げた以外にも落とし穴はいっぱいある ◦ 各種の画像フォーマット、その派生規格、画像処理、最適化、 etc… にそこそこ精通す る必要がある • 我々が本当に作りたかったのは Webアプリケーションであって画像変換エンジンじゃない

    ◦ なにかしらがないと顧客に価値(UX)を届けることはできないが、そのために画像変換 エンジンを自作するのはコストが高すぎる 33 生半可な覚悟で画像変換エンジンは作れない
  14. 36 :アップロード時にサーバサイドで加工 続き 36 • デザイナー < あ、デザイン変えたんでよろしく (^^) ◦

    全画像ファイル再生成 • Ap〇le < あ、新機種で解像度変えたんでよろしく (^^) ◦ 全画像ファイル再生成(※旧機種用も残す必要あり)
  15. 40

  16. • image_flux.gemというものがあります ◦ 宇宙海賊さん作 ◦ https://github.com/space-pirates-llc/image_flux 43 コード絶無は悲しいので、ご紹介 require ”image_flux”

    origin = ImageFlux::Origin.new(domain: ”demo.imageflux.jp”) origin.image_url(”/bridge.jpg”, width: 600) #=> ”https://demo.imageflux.jp/c/w=600/bridge.jpg”
  17. • ぼくと一緒に画像変換サービスを作ろうよ! ◦ 罠と課題はまだまだ無限にある ◦ 最強の画像変換SaaSを実現しよう! • 最近は動画変換サービス ImageFlux Live

    Streaming も開始 ◦ こちらの技術者ももちろん募集中 • https://recruit.jobcan.jp/pixiv/show/b001/2969 46 画像変換サービス開発たのしす