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

ご静聴ありがとうございました