Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
SwiftでAnimation PNGを仕様から作成してみた
Search
Manabu Otsu
February 27, 2023
Programming
1
400
SwiftでAnimation PNGを仕様から作成してみた
Example
https://gist.github.com/mbotsu/817c96b9a31901ec392fc8ba1389902a
Manabu Otsu
February 27, 2023
Tweet
Share
Other Decks in Programming
See All in Programming
コードレビューをしない選択 #でぃーぷらすトウキョウ
kajitack
3
1.1k
[PHPerKaigi 2026]PHPerKaigi2025の企画CodeGolfが最高すぎて社内で内製して半年運営して得た内製と運営の知見
ikezoemakoto
0
290
実践ハーネスエンジニアリング #MOSHTech
kajitack
7
3.6k
PHP 7.4でもOpenTelemetryゼロコード計装がしたい! / PHPerKaigi 2026
arthur1
1
410
20260320登壇資料
pharct
0
120
2026-03-27 #terminalnight 変数展開とコマンド展開でターミナル作業をスマートにする方法
masasuzu
0
140
new(1.26) ← これすき / kamakura.go #8
utgwkk
0
2.7k
S3ストレージクラスの「見える」「ある」「使える」は全部違う ─ 体験から見た、仕様の深淵を覗く
ya_ma23
0
1k
Migration to Signals, Signal Forms, Resource API, and NgRx Signal Store @Angular Days 03/2026 Munich
manfredsteyer
PRO
0
150
Codexに役割を持たせる 他のAIエージェントと組み合わせる実務Tips
o8n
4
1.4k
車輪の再発明をしよう!PHP で実装して学ぶ、Web サーバーの仕組みと HTTP の正体
h1r0
2
390
モックわからないマン卒業記 ~振る舞いを起点に見直した、フロントエンドテストにおけるモックの使いどころ~
tasukuwatanabe
3
420
Featured
See All Featured
Typedesign – Prime Four
hannesfritz
42
3k
We Are The Robots
honzajavorek
0
200
A Soul's Torment
seathinner
5
2.5k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Build your cross-platform service in a week with App Engine
jlugia
234
18k
The browser strikes back
jonoalderson
0
840
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
94
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
0
170
HDC tutorial
michielstock
1
580
GitHub's CSS Performance
jonrohan
1032
470k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
0
180
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.8k
Transcript
SwiftでAnimation PNGを 仕様から作成してみた インフォコム株式会社 技術企画室
目次 • 自己紹介 • 対象ユーザー • 開発に至る理由 ◦ 用途、問題点 ◦
Apple標準関数 • APNGを仕様から作成する ◦ PNGファイルフォーマット ◦ APNGファイルフォーマット ◦ コード分解 • まとめ
自己紹介 • 所属: インフォコム株式会社 技術企画室 • 最近はこんなことをしてます。 ◦ AMED採択プロジェクトでスマートフォンアプリの開発 ▪
https://www.infocom.co.jp/ja/news/news2022060801.html その他にも他社とのデータ分析の協力やその活用法の模索等をやっています。
プレゼンの対象となるユーザー • APNGを作成するApple標準関数に不満がある ◦ PNGのファイルサイズを減らしたい ▪ 24bit PNGを作りたい ▪ 圧縮したい
◦ 大きな(画素数やフレーム数の多い) Animation PNGを作りたい
開発に至る理由: どのような用途でAPNGを利用したいか • フレーム毎の分析データの可視化への利用(数百フレーム〜ある) • スプレッドシートの1行とフレームの1行を並べて比較したい
開発に至る理由: どのような問題から開発に至ったか 評価データ: 275フレーム x フルHDサイズ(1920x1080) x 50色のAnimation PNGを Appleの標準関数で作成すると端末のピーク時のメモリが
1GBになる
APNGを作成する為のApple標準関数 https://developer.apple.com/library/archive/documentation/GraphicsImaging/Conceptual/ImageIOGuide/ikpg_dest/ikpg_dest.html
APNGを作成する為のApple標準関数 • 追加した画像をバッファする為、多くのメモリを消費する • 圧縮サイズの指定もできない 以上からApple標準関数でAPNGを作るのは悩ましい。 CGImageのTrueColorは32bitの 画像データに限定 URLを渡してもストリームで書 き込むわけではない
APNGを仕様から作成する
PNGファイルフォーマット PNGはファイルシグネチャーと3つのチャンクで構成 PNGであることを示す 16進数の固定値が入る
Animation PNG(APNG)ファイルフォーマット PNGの仕様に3つの補助チャンクを追加した PNG拡張 • acTL: Animation Control ◦ フレーム数、ループ数
• fcTL: Frame Control ◦ シーケンス番号を持っており、フレームの 前に付ける。0から始まる。 ▪ 画像のサイズ ▪ 画像のオフセット ▪ フレームレート(分子/分母) • fdAT: Frame Data ◦ IDATにシーケンス番号を付与した画像 データ フレーム数に応じ て繰り返す
実際のコード
今回作るAnimation PNGの要件定義 • True Color 24bit PNG • 画像は1フレーム1枚、オフセットは使わない •
フレームレートは固定
はじめに: Byte, Binary データへのエンコード PNGはバイナリデータで記述する必要がある UInt32(4byte)、UInt16(2byte)は10進数のUInt8(1byte)に置 き換えた後にバイナリコード (Data型)に変換している
24bitのPNGを作成する 今回はPNGを扱うライブラリとしてOpenCVを利用します。 サンプルコードでは3フレームの移動する円の書き出しです。
コード: 初期化 PNGであることを示す16進数の固定値 Animation Control フレーム数、ループ数を設定 Image Header 画像のサイズや色深度、カラータ イプ等のヘッダ情報を含む
8: 8bit、2: True Color Frame Control フレームレートの設定 ・delayNum, 分子: numerator ・delayDen, 分母: denominator
チャンクの作成 チャンクはパターン化できる 1. frameCountとloopCountを結合してChunkDataを作成 2. ChunkTypeとChunkDataを結合 3. ChankDataから求めたLengthと2と2から求めたCRCを結合 ① ②
③
コード: フレームへの画像の追加 ① ② ③ ④ ⑤ ⑥ ⑦ ⑧
1. 引数: opencvで作成した画像 2. PNGに圧縮したバイナリデータを作成 3. signature(8)、IHDR(25)、IEND(12)を取り除いた IDATを作成 4. initで作成したfcTLにシーケンス番号を追加した チャンクを作成 5. 1フレーム目をストリームに出力 6. 1フレーム目以降をストリームに出力 7. IDATをブロックサイズ(8204)毎に分割 8. シーケンスを加算し、 fdATのチャンクを作成して ストリームに出力
opencv: imencodeの出力するPNG imencodeで出力すると、 IDATのChunkDataは8192byteのBlockSizeに分割して出力 3つに分割された場合、 3つ目には残りのデータ が入る
シーケンスナンバーの数え方 同じシーケンス番号を持つfcTLチャンクとfdATチャンクが 同居してはいけない
まとめ • SwiftでのAPNGの実装について話ました ◦ Apple標準関数では ▪ True Color 24bit Imageを作成できない
▪ 圧縮にも非対応 ▪ ストリーム出力にも非対応 ◦ 自作することで ▪ True Color 24bit に対応 ▪ 圧縮に対応 ▪ ストリーム出力にも対応 APNGは実装コード量も少なく、 ライブラリに困った時には自作もありではないでしょうか。
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
ご静聴ありがとうございました