【開発日記 #14】1秒で魔法がかかる!爆速APNG/GIFメーカー開発の裏側&ライブラリのバグをバイナリハックでねじ伏せた話
おはようございます!アイアイです。
ふと思い立って、こういう事はできないだろうかって、AIと突然相談始めることってありますよね?
今回はそんな思いつきから始まった試行錯誤の結果であります。
時には諦めも肝心ってこと。
えーん、早く自分でテストして間違ってたら自分で直してくれるAI社員たち帰ってきてえぇぇwww
いまだにクレジットは0のまま、戻ってきませんww
このクレジットいつ戻るのか、しばらく騙し騙し使っていきつつ様子を見たいと思います。
以下はGeminiに書かせた記事をアイアイがツッコミを入れつつ修正したものです。
今回は、ブラウザ上で誰でも一瞬でAPNG(動くPNG)やGIFアニメーションを作れるツール「簡単アニメ画像メーカー」の開発裏話をお届けします。
アイアイがそういうのを作り出したいと言い出して開発していたのですが、その途中にいくつか問題が発生しました。
画像ファイルをアップロードして、ボタンをポンと押すだけでうさぎさんなどの可愛いイラストが動き出す、とても楽しいツールなのですが……。 開発の途中、「2時間待っても完成しない恐怖のフリーズ事件」や、「1回だけ再生したいのに無限ループするライブラリの深すぎるバグ」に行く手を阻まれ、大苦戦しました。
今回は、そんな絶望的なバグたちをいかにして解決し、「1〜2秒で爆速完成する超安定版」に仕上げたのか、その舞台裏を大公開します!
🛠️ 今回作ったツールはこんなもの!
まずは完成したツールの紹介から。

機能: 画像(PNG/JPEG/GIF)をアップロードし、20種類以上のエフェクト(揺らす、点滅、ズーム、回転、虹色変化、ぷるぷるスライム、テレビノイズなど)を選択可能。
出力: X(旧Twitter)でそのまま動く「GIF形式」と、高画質な「APNG形式」をボタン一つでダウンロードできます。
ループ設定: 「無限ループ」と「1回だけ再生して停止」をワンクリックで切り替え可能!
💀 事件簿1:欲張って自爆した「複数エフェクト同時盛り」と恐怖のフリーズ
ツール開発が進み、エフェクトが20種類を超えた頃、アイアイが欲を出しました。
「虹色に変化しつつ、ぷるぷる震えながら、斜めに移動させたら最強に可愛いのでは!?」
そこで、複数のエフェクトをチェックボックスで何個でも重ね合わせられる「夢の同時盛り機能」を実装してみたのです。
しかし、これが悲劇の始まりでした。
実際に3つほどエフェクトを選択して「魔法をかける!」ボタンを押すと……。 画面が完全に固まり(フリーズ)、2時間待っても終わらない、ブラウザがハングアップする状態に。をいをいw
原因は「計算量の爆発」
動く画像(アニメーション)を作るには、画像を10枚のパラパラ漫画(コマ)にする必要があります。 1枚描くごとに、「色を変えて」「形を伸ばして」「揺らして」「ずらして」という複雑な計算を重ね、さらにそれをGIFの重いファイルへと変換する。これをすべてブラウザの1つの脳みそ(メインスレッド)でやらせた結果、処理の限界を超えて固まってしまったのです。
解決策:「原点回帰」と「役割分担」
ここで私たちは、最も大切なことに気づきました。 「使えないほど重い最強機能より、一瞬で動く安定した楽しさのほうが100倍素晴らしい!」
思い切って、複数選択のチェックボックスを廃止。エフェクトは1つだけ選ぶシンプルな「ラジオボタン」に原点回帰させました。 これだけで処理に必要な余分な計算が全てカットされ、一気に軽快になりました。
トホホ……💦
🐛 事件簿2:1回だけ再生したいのに!ライブラリの深すぎるバグ
次に立ちはだかったのが、「1回だけ再生してピタッと止まる画像(LINEスタンプのような挙動)」が作れないという問題でした。 無限ループのチカチカする画像だけでなく、1回だけ動く演出も作りたかったのですが、どれだけ「1回再生」を指定しても、出来上がるファイルは無限にループしてしまいます。
調査すると、使用していた外部ライブラリに、以下のような衝撃の仕様バグが潜んでいました。
GIF変換ライブラリ(gifshot)のバグ: 処理を爆速にするため「マルチスレッド(複数脳)」を有効にすると、なんと内部でループ回数の設定が自動的に消去され、強制的に無限ループになるというバグ。
APNG変換ライブラリ(UPNG.js)のブラウザによる解釈ズレ: APNGの規格が少し特殊なため、1回再生の指定をしても、一部のブラウザや画像ビューアがそれを無視して無限にループさせてしまう。
「マルチスレッドを止めて、シングルスレッドにすれば1回再生は作れるけれど、それだと画像生成に10秒以上待たされて重くなる……。」 という、スピード(爆速)を取るか、機能(1回再生)を取るかの地獄の2択を迫られたのです。
🪄 解決の切り札:データを直接書き換える「バイナリハック」
この究極の2択を、私たちは驚くべき「力技」で解決しました。 それが『バイナリハック(ファイルの直接書き換え)』です。
「ライブラリのプログラムがループ設定を消してしまうなら、出来上がった最終ファイルをプログラムで直接スキャンして、ループ回数を表すデータブロックを無理やり1回再生に書き換えてしまおう!」
という、バイナリ(機械語)レベルのハッキング処理を自作してツールに組み込みました。
GIFファイル: データの海から "NETSCAPE2.0" というループ回数を設定しているヘッダーを自力で探し出し、そのすぐ隣にある「無限(0)」の数値を「1回再生(1)」にピンポイントで書き換え。
APNGファイル: PNGの構造を解析し、アニメーション制御ブロックである "acTL" チャンクを直接書き換え、さらにエラーが起きないようCRC(データの整合性チェックサム)を自動再計算して書き込み。
この魔法のようなバイナリハックにより、「スレッド数を最大にして1〜2秒で爆速完成させる」と「1回再生の設定を完璧にファイルに刻み込む」という相反する2つの要望を、世界で初めて両立することに成功したのです!

🎨 さらに使いやすく、スタイリッシュなデザインへ!
機能が完璧になったので、最後にUI(見た目)を大改造しました。
2カラムの左右分割レイアウト: デスクトップで見ると、左側に「画像アップロードと設定」、右側に「プレビューとダウンロードボタン」が美しく配置されます。
スクロール追従(Sticky): 左側のたくさんのエフェクトを見ながら上下にスクロールしても、右側のプレビューとボタンが常に画面内に固定されて追いかけてきます。操作がとても快適になりました!
「もう一度再生」ボタン: 1回再生でピタッと止まってしまった画像を、いつでもその場でワンクリックでリプレイして確認できる親切設計にしました。
ここは、AIくんのドヤ顔ポイントですねw
💡 まとめ&開発を終えて
今回の開発は、「機能を追加すればするほど、処理が重くなって使えなくなる」というプログラミングで誰もが陥る罠を体感した、非常に学びの多い一日でした。
大切なのは、技術を詰め込むことではなく、ユーザーが手元で触ったときに「うわ、動いた!楽しい!しかも一瞬で作れた!」と感じる感動の体験(UX)を最優先にすること。
複数選択を捨て、シンプルな1エフェクトの仕組みに戻し、ライブラリのバグをバイナリハックという禁じ手(?)でねじ伏せたことで、これ以上ないほど「サクサク動き、思い通りに機能する最強のツール」が完成しました。
このツールが、誰かのお気に入りの画像に「動く魔法」をかけるきっかけになれば嬉しいです。
現在、追加で色んな効果を作ってるところです。
最後まで読んでいただき、ありがとうございました!
手探りでAntigravityくんと戯れているのを見るなら、こちらから
てかさぁ、土日丸一日予定があると、noteゆっくり見る時間もないやw
記事はかろうじて書き溜めあるから投稿できるんだけどさ。
楽しいTRPGのセッションなので、仕方ないんだけど!!
#APNG #GIFアニメ #画像加工 #Web開発 #JavaScript #個人開発 #バグ修正 #プログラミング #異次元ポケット
いいなと思ったら応援しよう!
応援よろしくお願いします!!
頂いたチップはクリエイターとしての活動費に使わせていただきます!