SwiftでAnimation PNGを仕様から作成してみた
by
Manabu Otsu
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
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
ご静聴ありがとうございました