libGDを使う
どうも、吉村です。
最近Twitterが今更ながら、今更ながら、GIFアニメの投稿をサポートしました。
なのでGIFアニメを投稿する機能の実装を迫られた方も一定数いらっしゃるのではないでしょうか。
というわけで今回はiOSでGIFアニメーションを生成してみましょう。
ところでiOSのImageIO.frameworkには、GIFアニメーションを生成できる関数がありますが、
今回はこれは使いません。
なぜかというと、ファイルサイズが大きくなるとどうも色が不安定で、
正しいGIFを出してくれないからです。
フレームワークのバグなのか仕様なのかわかりませんが、とにかく調子が悪いため、
libGDというGIFフレームワークを今回は使ってみます。
GD Graphics Library
http://libgd.bitbucket.org/
さて、このライブラリ、iOSに対応している訳ではありません。
なので、iOSで使うためには一手間必要です。
とはいっても、
1、必要そうなファイルを抽出してプロジェクトに追加
2、ビルドエラーになる部分を修正
3、必要に応じてワーニングを確認・修正
というプロセスを経れば、少し時間がかかりますが、実行できる様になります。
でも、この記事を読んでいただいている方は、そんな面倒なことをする必要はありません。
是非、こちらをご利用ください。
https://github.com/wowdevjp/libGD_iOS
ソースをプロジェクトにコピーですぐにlibGDを使い始めることが出来ます。
というわけで、GIFアニメーションを生成するコードを見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
#import "LGBViewController.h" #include "gd.h" static double remap(double value, double inputMin, double inputMax, double outputMin, double outputMax) { return (value - inputMin) * ((outputMax - outputMin) / (inputMax - inputMin)) + outputMin; } @implementation LGBViewController { IBOutlet UIWebView *_webView; } - (void)viewDidLoad { [super viewDidLoad]; NSString *tmpDir = NSTemporaryDirectory(); NSString *tmpPath = [tmpDir stringByAppendingPathComponent:@"tmp.gif"]; FILE *fp = fopen(tmpPath.UTF8String, "wb"); int width = 300; int height = 300; int frameRate = 10; int delay = (int)round((1.0 / (double)frameRate) * 100.0); gdImagePtr image = gdImageCreate(width, height); gdImageGifAnimBegin(image, fp, FALSE, 0); int frameCount = frameRate * 6; for(int i = 0 ; i < frameCount ; ++i) { gdImagePtr frameImage = gdImageCreateTrueColor(width, height); double elapsed = (1.0 / (double)frameRate) * i; for(int y = 0 ; y < height ; ++y) { double offsety = remap(y, 0, height - 1, 0, 10); for(int x = 0 ; x < width ; ++x) { double offsetx = remap(x, 0, width - 1, 0, 10); uint8_t r = ABS(sin(offsetx + elapsed)) > 0.7 ? 255 : 0; uint8_t g = ABS(cos(offsetx + elapsed)) > 0.7 ? 255 : 0; uint8_t b = ABS(sin(offsety + elapsed)) > 0.7 ? 255 : 0; gdImageSetPixel(frameImage, x, y, gdTrueColor(r, g, b)); } } gdImageTrueColorToPalette(frameImage, TRUE, gdMaxColors); gdImageGifAnimAdd(frameImage, fp, TRUE, 0, 0, delay, gdDisposalNone, NULL); gdImageDestroy(frameImage); } gdImageGifAnimEnd(fp); fclose(fp); gdImageDestroy(image); NSData *gif = [NSData dataWithContentsOfFile:tmpPath]; [_webView loadData:gif MIMEType:@"image/gif" textEncodingName:@"UTF-8" baseURL:nil]; } @end |
gdImageCreateで画像オブジェクトを作成後、
C言語のファイルポインタを使って、
gdImageGifAnimBegin, gdImageGifAnimAdd, gdImageGifAnimEnd
でGIFアニメーションを出力します。
フレームレートの指定がGIFは少々特殊なので注意しましょう。
作っただけだと正しく出来ているのか疑問なので、UIWebViewで表示しています。
実際に完成したアニメーションGIFは以下のようになります。
APIの規則にそっている限り、なんら難しい点はありませんが、
今回実際Twitterに上げる場合、サイズ制限があるので、そちらの対応のほうが面倒かと思います。
最後に、今回この記事をかくきっかけになった、自社アプリ、mopicoを宣伝して終わろうと思います。
mopico( モピコ ) は、写真と動画をデコ・加工・編集して、
動くコラージュを作ることができる新感覚のアプリです。
是非無料ですのでダウロードしてみてください。