スプライトシート軽量化テクニック(JPEG分割 vs 減色)

開発部の山崎です。今回は、スプライトシートのファイル容量を軽減するためのテクニックをご紹介いたします。

Adobe Flash CS6には「スプライトシート」を出力する機能があります。スプライトシートを使うと、Flash Playerを使わずに、ブラウザ上でパラパラマンガ方式のアニメーションを表示することができます。現在主流のブラウザ(IE9を除く)であれば、CSSやJavaScriptを使って容易にアニメーションを表示することができます。最近は、Flashに対応していないスマートフォンでWebを閲覧する機会が増えていることから、注目されている機能です。

本記事では、このスプライトシートのファイル容量を軽減するための方法について考察してみます。

ちなみに、弊社製品の「OPTPiX SpriteStudio」と「OPTPiX imésta」を組み合わせて、スプライトシートを作成することも可能です。

Adobe Flash CS6が出力するスプライトシートの問題点

Adobe Flash CS6では「スプライトシート」を出力する際、PNG8またはPNG32の2種類の画像フォーマットが選択できます。しかしながら、PNG8はファイルサイズは小さいのですが画質がいまひとつで、逆にPNG32は画質は良いのですがファイルサイズが大きいと、多くのクリエイターが頭を抱えているようです。

アニメーションを表示する際は、出力するコマ数も問題になります。コマ数が少ないとカクカクとしたぎこちない表示になってしまうので、なめらかなアニメーションを表示するにはコマ数を増やす必要があります。必然的に、画像ファイルサイズがクローズアップされるわけです。

比較サンプルとして、PNG32とPNG8のアルファ付画像を以下に示します。

 Flashから出力したスプライトシートの例(PNG32bit) Flashから出力したスプライトシートの例(PNG8bit)
 Adobe Flash CS6で出力したPNG32画像
149,599バイト
ファイルサイズが大きい
 Adobe Flash CS6で出力したPNG8画像
39,948バイト(PNG32比26.7%)
画質が悪い
▲ Flashから出力したスプライトシートの例
(PNG32はPNG8に比べて画質は良いがファイルサイズは3.7倍ほど大きい)

この記事では、画質を比較しやすくするために、実際のスプライトシートのようにパラパラ画像ではなく、1枚画像で例示しています。また、前述のようにIE9ではスプライトシートを表示できないため、スプライトシートを本ページ上でそのまま表示せず、Chromeで表示した画像をキャプチャしたものを使用しています。元のスプライトシート画像ファイルを参照したい場合は、本記事の最後をご覧ください。

JPEGに分割し軽量化するテクニックが流行中

スプライトシートのファイルサイズが大きくなってしまう問題では多くのクリエイターが困っているようで、最近になって、出力されたPNG32ファイルを加工することで画質を維持したままトータルのファイルサイズを減らすテクニックを見かけるようになりました。

そのテクニックとは、「PNG32の画像を『JPEGファイル』と『アルファチャンネルのみのPNG32ファイル』の2つに分割することでトータルのファイルサイズを減らす」というものです。表示の際は、分割した2つの画像を合成することでスプライトシートに戻すのです。

スプライトシートが写真のような画像主体であれば、PNG32よりもJPEGのほうが高い圧縮率が期待できます。

ただし、JPEGにはアルファチャンネルを含めることができないため、JPEGだけでは背景の透けない画像になってしまいます。そこで苦肉の策(?)として、アルファチャンネルのみをPNGに残して情報を補完し、合成表示するというアイディアが生まれたのです。以降、アルファチャンネルのみ格納したPNGファイルのことを、本記事ではPNG*(A)と表記することにします。この表記は、本記事独自のものです。

PNG32のスプライトシートを、JPEGとPNG(A)に分割するにはAdobe Flash CS6の機能だけではできないので、他の画像加工ツールが必要になります。弊社の「OPTPiX imésta 7 for Mobile & Social」を使えばJPEGへの変換も、PNG32(A)の出力も容易に行えます。

この分割テクニックは、アルファの情報をPNG32(A)で作成することを前提として広く紹介されていますが、インデックスカラーのPNG8(A)ファイルとして出力すれば、アルファチャンネルが失われることなくさらに小さく軽量化することが可能になります。

いくつかのサンプル画像を実際に作成して試してみたところ、PNG32で作成するよりもPNG8で作成したほうが10%~30%ほど小さく軽量化されることが確認できました(PNGファイル部分だけの比較)。従って、以下にご紹介するサンプル画像のPNG(A)画像は、すべてPNG8で作成しています。

さらに細かい話になりますが、アルファチャンネルのみをグレースケールのPNGにするという手段もあります。この場合、パレット情報の部分が無くなるため、さらにファイルを小さくできます。

しかし、グレースケールにしてしまうと単純な合成表示ができなくなり、合成する前にアルファチャンネルへの変換処理が必要になります。すなわち合成表示のJavaScriptのコードに大きく手を入れる必要があります。作成の手間と合成の手間を考えた結果として、ここでは敢えてPNG8を選択しました。

Adobe Flash CS6で出力したPNG8画像 Adobe Flash CS6で出力した JPEG+アルファチャンネル付きPNG8画像
Adobe Flash CS6で出力したPNG8画像
39,948バイト(PNG32比26.7%)
PNG32をJPEG+PNG8(A)画像に変換して
表示した画像
38,583バイト(PNG32比25.8%)

▲ JPEGとPNG8(A)に分割出力したあと合成表示した画像の例
特に影の部分がきれいに透けています

しかしながら、このJPEG+PNG8(A)分割テクニックにも、以下のようにいくつか弱点があります。これらの弱点とメリットを天秤に掛けて、分割テクニックの採否を検討してください。

  • 分割した画像を合成して表示する際、ブラウザのcanvasタグの機能を使って描画しているため、ブラウザの種類によっては表示されない(*1)
  • JavaScriptで2つの画像を合成するため、表示されるまでに若干のタイムラグがある。画像が大きくなったり表示枚数が増えることでさらに影響が大きくなる
  • JPEGとPNG(A)ファイルに分割する作業が面倒
  • 2種類の画像を管理するのが面倒

*1 IE9はcanvasタグの互換性の問題で正しく表示できません。スマートフォン(AndroidやiOS)のブラウザでは合成表示が可能ですが、フィーチャーフォン(ガラケー)では合成表示できません。

アルファチャンネル込みで減色した画像との比較

PNGのファイルサイズを小さく軽量化する手段の1つに減色というテクニックがあります。ただし、Photoshopの減色機能ではアルファチャンネル付インデックスカラーへの減色ができませんので、スプライトシートを軽量化するのであれば「OPTPiX imésta 7 for Mobile & Social」のようにアルファチャンネル込みで減色できるツールを使う必要があります。

ここではiméstaの減色機能を使い、PNG32のスプライトシートをPNG8に変換し、JPEG+PNG8(A)へ分割後合成表示した場合との画質を比較 してみることにします。

比較を公正に行う目的で、いくつかの画像を用意しました。

  • 写真を切り抜いたタイプ
  • カードゲームに使われるようなイラスト
  • グラデーションのある文字や半透明効果の入ったボタン

詳しくは、エントリー最後にあるzipファイルをご覧ください。結果を画質のみで比較できるように、圧縮後のファイルサイズが揃うようにJPEGの圧縮率を変えています。

次に、特徴的な結果となった画像を3種類ほどピックアップして紹介します。なお、拡大画像はいずれも白枠内の部分を3倍に拡大したものです。

写真を切り抜いたタイプ

写真を切り抜いた画像などは、JPEGに分割するときれいに表示されます。iméstaによる減色も負けていませんが、このようなスプライトシートを作成する場合は、(画像によりますが)JPEGに分割するほうが画質的に良い結果が得られる場合があります。

Adobe Flash CS6で出力した JPEG+アルファチャンネル付きPNG8画像 OPTPiX iméstaで減色処理したPNG8画像
PNG32をJPEG+PNG8(A)画像に変換して
表示した画像

38,583バイト(PNG32比25.8%)
OPTPiX iméstaで減色処理したPNG8画像
39,933バイト(PNG32比26.7%)

カードゲームに使われるようなイラスト

イラストなどの画像になると、JPEG分割ではモスキートノイズが目立ちクッキリと表示されず、PNG8に比べてモヤっとしてきます。

イラストA

Adobe Flash CS6で出力した JPEG+アルファチャンネル付きPNG8画像▲PNG32をJPEG+PNG8(A)画像に変換して表示した画像
16,657バイト(PNG32比31.8%)

OPTPiX iméstaで減色処理したPNG8画像▲OPTPiX iméstaで減色処理したPNG8画像
16,858バイト(PNG32比32.2%)

イラストB

Adobe Flash CS6で出力した JPEG+アルファチャンネル付きPNG8画像▲PNG32をJPEG+PNG8(A)画像に変換して表示した画像
40,464バイト(PNG32比30.2%)

OPTPiX iméstaで減色処理したPNG8画像▲OPTPiX iméstaで減色処理したPNG8画像
40,754バイト(PNG32比30.5%)

グラデーションのある文字や半透明の入ったボタン

文字やボタンでは、JPEGに分割してしまうとかなり激しく崩れてしまいます。色数が少なめでクッキリと表示したい画像はJPEGには向いていません。

グラデーションのある文字

Adobe Flash CS6で出力した JPEG+アルファチャンネル付きPNG8画像▲PNG32をJPEG+PNG8(A)画像に変換して表示した画像
25,371バイト(PNG32比58.9%)

OPTPiX iméstaで減色処理したPNG8画像▲OPTPiX iméstaで減色処理したPNG8画像
22,330バイト(PNG32比51.8%)

半透明の入ったボタン

Adobe Flash CS6で出力した JPEG+アルファチャンネル付きPNG8画像▲PNG32をJPEG+PNG8(A)画像に変換して表示した画像
24,732バイト(PNG32比50.3%)

OPTPiX iméstaで減色処理したPNG8画像▲OPTPiX iméstaで減色処理したPNG8画像
25,130バイト(PNG32比51.1%)

結論 スプライトシートにはインデックスカラーが最適

スプライトシートのファイルサイズを最適化するには、JPEGとPNGの2枚の画像を管理したり、JavaScriptで合成しなければならない手間やマルチプラットフォームへの対応などを考えると、写真系の画像であっても一括してiméstaを使ってPNG8への変換がオススメできると言えそうです。

比較用参考画像

最後に、比較に使用したすべてのサンプル画像をzipファイルにまとめました。
更に詳しい情報を見てみたい、という方はダウンロードしてご覧ください。

スプライトシートのサンプルファイルをダウンロードする(spritesheet_sample.zip : 824KB)

タグ , , , , | 2020/06/16 更新 |