Pebble SDK では、GBitmapSequence API を使用してアプリ内でアニメーション画像を再生できます。この API は APNG 画像を入力ファイルとして受け取ります。APNG ファイルはよく知られている .gif ファイルに似ていますが、.gif は直接サポートされていないため、APNG に変換できます。
同様の効果は、複数の画像リソース、BitmapLayer、および AppTimer を使用して実現できますが、はるかに多くのコードが必要になります。GBitmapSequence API は、読み取り、解凍、フレームの期間/カウントを自動的に処理します。
.gif ファイルは、gif2apng と -z0 フラグを使用して APNG .png 形式に変換できます:
./gif2apng -z0 animation.gif
Note: ファイル拡張子は
.pngでなければなりません。.apngではありません。
package.json の resources 配列に、raw リソースとして APNG ファイルを含めます:
"resources": {
"media": [
{
"type":"raw",
"name":"ANIMATION",
"file":"images/animation.png"
}
]
}
GBitmapSequence は GBitmap をコンテナとして使用し、APNG ファイルから新しいフレームが読み取られるたびにその内容を更新します。つまり、最初のステップは、このコンテナとなる空白の GBitmap を作成することです。
データを保持するファイルスコープ変数を宣言します:
static GBitmapSequence *s_sequence;
static GBitmap *s_bitmap;
リソースから APNG を GBitmapSequence 変数に読み込み、フレーム サイズを使用して空白の GBitmap フレーム コンテナを作成します:
// Create sequence
s_sequence = gbitmap_sequence_create_with_resource(RESOURCE_ID_ANIMATION);
// Create blank GBitmap using APNG frame size
GSize frame_size = gbitmap_sequence_get_bitmap_size(s_sequence);
s_bitmap = gbitmap_create_blank(frame_size, GBitmapFormat8Bit);
アプリがアニメーション画像の再生を開始する準備ができたら、AppTimer を使用して、シーケンスの最後に到達するまで各フレームを進めます。次の APNG フレームの読み込みは自動的に処理され、コンテナ GBitmap に書き込まれます。
現在のフレームを表示する BitmapLayer 変数を宣言し、Displaying An Image で説明されているように設定します。
static BitmapLayer *s_bitmap_layer;
AppTimer が経過し、次のフレームを表示する必要があるときに使用されるコールバックを作成します。これは、フレームがなくなり、gbitmap_sequence_update_bitmap_next_frame() が false を返すまでループで発生します:
static void timer_handler(void *context) {
uint32_t next_delay;
// Advance to the next APNG frame, and get the delay for this frame
if(gbitmap_sequence_update_bitmap_next_frame(s_sequence, s_bitmap, &next_delay)) {
// Set the new frame into the BitmapLayer
bitmap_layer_set_bitmap(s_bitmap_layer, s_bitmap);
layer_mark_dirty(bitmap_layer_get_layer(s_bitmap_layer));
// Timer for that frame's delay
app_timer_register(next_delay, timer_handler, NULL);
}
}
適切なタイミングで、AppTimer を使用して最初のフレームの進行をスケジュールします:
uint32_t first_delay_ms = 10;
// Schedule a timer to advance the first frame
app_timer_register(first_delay_ms, timer_handler, NULL);
アプリが終了するか、リソースが不要になったら、GBitmapSequence とコンテナ GBitmap を破棄します:
gbitmap_sequence_destroy(s_sequence);
gbitmap_destroy(s_bitmap);