yoshida_eth0の日記 このページをアンテナに追加 RSSフィード

2010-11-26

MacとiPhoneでアニメーションGIFを表示する方法まとめ

まとまってるページがなさそうだったから、調べた事をメモ。

 

Macの場合

AppKitのNSImageを使えば勝手に動く。

サイズ17x17、コマ数3、描画時間1コマ辺り0.1秒、のGIFを表示させるのに、CPUを1.5%位使い続ける。

どうやらアニメーションGIFの描画は重いらしい。

 

iPhoneの場合 - 複数の静止画を指定してUIImageViewで表示

NSImageと似たような感じでUIKitにUIImageというクラスがあるけど、GIFは動かない。

この方法は、複数の静止画を時間で切り替えてアニメーションさせる。

 

メリット

・PNG等のフォーマットが使えるので、GIFでは表現出来ない色も使える。

 

デメリット

・既存のGIFファイルをそのまま使う事が出来ない。

 

参考URL

[iPhone][tips] UIImageで手っ取り早くアニメーションを作ってしまう方法 - Ni chicha, ni limona - 平均から抜けられない僕 - iPhoneアプリ開発グループ

http://iphone-dev.g.hatena.ne.jp/paella/20090924/1253764989

 

iPhoneの場合 - 1つのアニメーションGIFを指定してUIImageViewで表示

アニメーションGIFのバイナリデータを解析して、複数のUIImageを生成して、以下同上。

 

メリット

・既存のGIFファイルをそのまま使う事が出来る。

 

デメリット

・GIFファイルのフォーマットによっては背景色が変になる事がある。

・非同期で生成されるため、生成し終わるまで画像のサイズを取得出来ない。

 

ソース
- (void)viewDidLoad {
	NSString *path = [NSString stringWithFormat:@"%@/%@", [[NSBundle mainBundle] resourcePath], @"aaa.gif"];
	UIImage *img = [UIImage imageNamed:path];
	path = [path stringByReplacingOccurrencesOfString:@"/" withString:@"//"];
	path = [path stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
	NSURL *imgurl = [NSURL URLWithString: [NSString stringWithFormat:@"file:/%@", path]];
	UIImageView *imageView = [AnimatedGif getAnimationForGifAtUrl:imgurl];
	[imageView setFrame:CGRectMake(0.0, 0.0, img.size.width, img.size.height)];
	[self.view addSubview:imageView];
}

 

参考URL

[GIF][UIImageView] アニメーションGIFをUIImageViewで(無理矢理)表示する - Ni chicha, ni limona - 平均から抜けられない僕 - iPhoneアプリ開発グループ

http://iphone-dev.g.hatena.ne.jp/paella/20100105/1262705713

 

iPhoneの場合 - 1つのアニメーションGIFをUIWebViewで表示

Safariの機能を使って表示する。

 

メリット

・既存のGIFファイルをそのまま使う事が出来る。

・Safariで表示出来るGIFファイルなら確実に表示出来る。

 

デメリット

・画像のサイズを取得出来ない。

・一度に大量に生成したりすると、描画されるまでに時間がかかる。

・大量にaddSubviewしてるとCPUを使い過ぎて、ページングもままならない位重い。(removeFromSuperviewすれば軽くなる)

 

ソース

imgタグだけのHTMLを表示させるのと、画像URLから表示させるの、複数同時に生成した時の描画時間が若干違う気がする。

多分、メインスレッドが重いか、UIWebViewのスレッドが重いか、の違いなんじゃないかと思われる。

(HTMLの読み込みは非同期で行われる)

- (void)viewDidLoad {
	NSString *path = [NSString stringWithFormat:@"%@/%@", [[NSBundle mainBundle] resourcePath], @"aaaa.gif"];
	NSString *htmlSource = htmlSource = [NSString stringWithFormat:@"<img src='file://%@' />", path];
	UIImage *img = [UIImage imageNamed:path];
	UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(-8, -8, img.size.width+8, img.size.height+8)];
	[webView loadHTMLString:htmlSource baseURL:nil];
	[self.view addSubview:webView];
	[webView release];
}

 

参考URL

iPhoneネイティブアプリでアニメーションGIFを表示する方法 -

このブログは証明できない。

http://d.hatena.ne.jp/shunsuk/20090915/1253005008

 

iPhoneの場合 - 1つのアニメーションGIFをUIWebBrowserViewで表示

UIWebViewの中から必要なView1つだけを取ってくる。

 

メリット

・既存のGIFファイルをそのまま使う事が出来る。

・Safariで表示出来るGIFファイルなら確実に表示出来る。

・UIWebViewで表示するより軽い。

 

デメリット

・画像のサイズを取得出来ない。

Appleに申請して、審査が通るか不明。(人柱募集中)

・今後のiOSのバージョンが上がっても使えるという保証がない。

 

ソース
- (void)viewDidLoad {
	NSString *path = [NSString stringWithFormat:@"%@/%@", [[NSBundle mainBundle] resourcePath], @"aaaa.gif"];
	NSString *htmlSource = htmlSource = [NSString stringWithFormat:@"<img src='file://%@' />", path];
	UIImage *img = [UIImage imageNamed:path];
	self.webView = [[UIWebView alloc] initWithFrame:CGRectMake(-8, -8, img.size.width+8, img.size.height+8)];
	[webView loadHTMLString:htmlSource baseURL:nil];
	id browserView = [[[[webView subviews] lastObject] subviews] lastObject];
	[browserView setFrame:CGRectMake(-8, -8, img.size.width+8, img.size.height+8)];
	[self.view addSubview:browserView];
}

 

参考URL

ビュー (UIView) の階層構造をダンプする非公開の便利メソッド - 24/7 twenty-four seven

http://d.hatena.ne.jp/KishikawaKatsumi/20100521/1274451944

nanashinanashi 2010/12/07 18:03 最後の方法を試してみたのですが、私の環境ではwebViewをリリースするタイミングで内部のbrowserViewも一緒にリリースされてしまうようなのですが、実際に上手く行くでしょうか?
もしよろしければ参考URLなど示しては頂けないでしょうか

eth0jpeth0jp 2010/12/08 04:07 コメントありがとうございます。
コピーした時にミスったようです。
自分のプロジェクトを見てみたら、webViewはインスタンス変数として、deallocでreleaseしていました。

http://d.hatena.ne.jp/KishikawaKatsumi/20100521/1274451944 を見て自分で書いたコードなので、参考URLは特にありません。
なので、簡単に解説します。
UIWebBrowserViewを使う場合、UIWebViewのインスタンスをずっと保持していなければいけないのでメモリは食いますが、不要なViewを表示しないで済むので、CPUの使用率を抑える事が出来ます。
UIScrollViewに、UIWebViewを100個addSubviewしたものと、UIWebBrowserViewを100個addSubviewしたものだと、スクロールの滑らかさが歴然です。(現実的な実装ではないですが)
シミュレータでは違いが解りづらいですが、実機で確認してみると動きがかなり違います。

本文、若干修正しました。

nanashinanashi 2010/12/08 07:26 ありがとうございます。
それですと、例えば3個gif画像を表示したい場合は、UIWebViewのインスタンスを3個解放せずに保持しておくことになる、ということであってますでしょうか。

eth0jpeth0jp 2010/12/08 17:52 そうですね。
個数が少なく固定なら、インスタンス変数を個数分定義すればいいかと思います。
個数が非固定、または大量にある場合は、インスタンス変数にNSMutableArrayやNSMutableDictionaryなどを1つ用意して、それに対してUIWebViewのインスタンスを追加していく、という方が管理しやすいんじゃないかと思います。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/eth0jp/20101126/1290707742
Connection: close