SwiftでAnimation PNGを仕様から作成してみた
by
Manabu Otsu
×
Copy
Open
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Slide 1
Slide 1 text
SwiftでAnimation PNGを 仕様から作成してみた インフォコム株式会社 技術企画室
Slide 2
Slide 2 text
目次 ● 自己紹介 ● 対象ユーザー ● 開発に至る理由 ○ 用途、問題点 ○ Apple標準関数 ● APNGを仕様から作成する ○ PNGファイルフォーマット ○ APNGファイルフォーマット ○ コード分解 ● まとめ
Slide 3
Slide 3 text
自己紹介 ● 所属: インフォコム株式会社 技術企画室 ● 最近はこんなことをしてます。 ○ AMED採択プロジェクトでスマートフォンアプリの開発 ■ https://www.infocom.co.jp/ja/news/news2022060801.html その他にも他社とのデータ分析の協力やその活用法の模索等をやっています。
Slide 4
Slide 4 text
プレゼンの対象となるユーザー ● APNGを作成するApple標準関数に不満がある ○ PNGのファイルサイズを減らしたい ■ 24bit PNGを作りたい ■ 圧縮したい ○ 大きな(画素数やフレーム数の多い) Animation PNGを作りたい
Slide 5
Slide 5 text
開発に至る理由: どのような用途でAPNGを利用したいか ● フレーム毎の分析データの可視化への利用(数百フレーム〜ある) ● スプレッドシートの1行とフレームの1行を並べて比較したい
Slide 6
Slide 6 text
開発に至る理由: どのような問題から開発に至ったか 評価データ: 275フレーム x フルHDサイズ(1920x1080) x 50色のAnimation PNGを Appleの標準関数で作成すると端末のピーク時のメモリが 1GBになる
Slide 7
Slide 7 text
APNGを作成する為のApple標準関数 https://developer.apple.com/library/archive/documentation/GraphicsImaging/Conceptual/ImageIOGuide/ikpg_dest/ikpg_dest.html
Slide 8
Slide 8 text
APNGを作成する為のApple標準関数 ● 追加した画像をバッファする為、多くのメモリを消費する ● 圧縮サイズの指定もできない 以上からApple標準関数でAPNGを作るのは悩ましい。 CGImageのTrueColorは32bitの 画像データに限定 URLを渡してもストリームで書 き込むわけではない
Slide 9
Slide 9 text
APNGを仕様から作成する
Slide 10
Slide 10 text
PNGファイルフォーマット PNGはファイルシグネチャーと3つのチャンクで構成 PNGであることを示す 16進数の固定値が入る
Slide 11
Slide 11 text
Animation PNG(APNG)ファイルフォーマット PNGの仕様に3つの補助チャンクを追加した PNG拡張 ● acTL: Animation Control ○ フレーム数、ループ数 ● fcTL: Frame Control ○ シーケンス番号を持っており、フレームの 前に付ける。0から始まる。 ■ 画像のサイズ ■ 画像のオフセット ■ フレームレート(分子/分母) ● fdAT: Frame Data ○ IDATにシーケンス番号を付与した画像 データ フレーム数に応じ て繰り返す
Slide 12
Slide 12 text
実際のコード
Slide 13
Slide 13 text
今回作るAnimation PNGの要件定義 ● True Color 24bit PNG ● 画像は1フレーム1枚、オフセットは使わない ● フレームレートは固定
Slide 14
Slide 14 text
はじめに: Byte, Binary データへのエンコード PNGはバイナリデータで記述する必要がある UInt32(4byte)、UInt16(2byte)は10進数のUInt8(1byte)に置 き換えた後にバイナリコード (Data型)に変換している
Slide 15
Slide 15 text
24bitのPNGを作成する 今回はPNGを扱うライブラリとしてOpenCVを利用します。 サンプルコードでは3フレームの移動する円の書き出しです。
Slide 16
Slide 16 text
コード: 初期化 PNGであることを示す16進数の固定値 Animation Control フレーム数、ループ数を設定 Image Header 画像のサイズや色深度、カラータ イプ等のヘッダ情報を含む 8: 8bit、2: True Color Frame Control フレームレートの設定 ・delayNum, 分子: numerator ・delayDen, 分母: denominator
Slide 17
Slide 17 text
チャンクの作成 チャンクはパターン化できる 1. frameCountとloopCountを結合してChunkDataを作成 2. ChunkTypeとChunkDataを結合 3. ChankDataから求めたLengthと2と2から求めたCRCを結合 ① ② ③
Slide 18
Slide 18 text
コード: フレームへの画像の追加 ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ 1. 引数: opencvで作成した画像 2. PNGに圧縮したバイナリデータを作成 3. signature(8)、IHDR(25)、IEND(12)を取り除いた IDATを作成 4. initで作成したfcTLにシーケンス番号を追加した チャンクを作成 5. 1フレーム目をストリームに出力 6. 1フレーム目以降をストリームに出力 7. IDATをブロックサイズ(8204)毎に分割 8. シーケンスを加算し、 fdATのチャンクを作成して ストリームに出力
Slide 19
Slide 19 text
opencv: imencodeの出力するPNG imencodeで出力すると、 IDATのChunkDataは8192byteのBlockSizeに分割して出力 3つに分割された場合、 3つ目には残りのデータ が入る
Slide 20
Slide 20 text
シーケンスナンバーの数え方 同じシーケンス番号を持つfcTLチャンクとfdATチャンクが 同居してはいけない
Slide 21
Slide 21 text
まとめ ● SwiftでのAPNGの実装について話ました ○ Apple標準関数では ■ True Color 24bit Imageを作成できない ■ 圧縮にも非対応 ■ ストリーム出力にも非対応 ○ 自作することで ■ True Color 24bit に対応 ■ 圧縮に対応 ■ ストリーム出力にも対応 APNGは実装コード量も少なく、 ライブラリに困った時には自作もありではないでしょうか。
Slide 22
Slide 22 text
References ● PNGファイルフォーマット ○ https://www.setsuki.com/hsp/ext/png.htm ● APNGの構造とRubyでの読み書き ○ https://nacl-ltd.github.io/2016/12/08/apng-and-ruby.html 今回のコードはこちらで公開しています https://gist.github.com/mbotsu/817c96b9a31901ec392fc8ba1389902a
Slide 23
Slide 23 text
ご静聴ありがとうございました