74

シンプルなフレームごとのパラパラ漫画スタイルでアニメーション化されている iOS アプリ内に、ユーザーがカスタマイズした一連の画像があります。

私の質問はこれです: ユーザーがアニメーションをアニメーション gif としてエクスポートできるようにする方法はありますか? 理想的には、メール、ソーシャル共有 (T/FB)、または (最悪の場合..) アニメーション GIF をドキュメント フォルダーに保存して、iTunes 経由で取得できるようにしたいと考えています。

.png をフォト ライブラリに保存する方法を知っていて、アニメーションを QT ファイルとして記録する方法を見つけました ( http://www.cimgf.com/2009/02/03/record-your-core-animation -animation/ )、しかし、単純な古いアニメーション gif を追い出す方法が見つかりませんでした。コア アニメーションまたは他の場所で何か不足していますか? 誰もが推奨できるアプローチ、フレームワーク、またはリソースはありますか? 質問が一般的すぎる場合は申し訳ありません - 出発点を見つけるのに苦労しています。

4

3 に答える 3

161

Image I/O フレームワーク (iOS SDK の一部) を使用して、アニメーション GIF を作成できます。MobileCoreServicesGIF 型定数を定義するフレームワークも含める必要があります。次のように、これらのフレームワークをターゲットに追加し、アニメーション GIF を作成するファイルにそれらのヘッダーをインポートする必要があります。

#import <ImageIO/ImageIO.h>
#import <MobileCoreServices/MobileCoreServices.h>

例で説明するのが最も簡単です。iPhone 5 でこの GIF を作成するために使用したコードを紹介します。

示されているコードによって作成されたアニメーション GIF

UIImageまず、サイズと角度を受け取り、その角度で赤い円盤の を返すヘルパー関数を次に示します。

static UIImage *frameImage(CGSize size, CGFloat radians) {
    UIGraphicsBeginImageContextWithOptions(size, YES, 1); {
        [[UIColor whiteColor] setFill];
        UIRectFill(CGRectInfinite);
        CGContextRef gc = UIGraphicsGetCurrentContext();
        CGContextTranslateCTM(gc, size.width / 2, size.height / 2);
        CGContextRotateCTM(gc, radians);
        CGContextTranslateCTM(gc, size.width / 4, 0);
        [[UIColor redColor] setFill];
        CGFloat w = size.width / 10;
        CGContextFillEllipseInRect(gc, CGRectMake(-w / 2, -w / 2, w, w));
    }
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

これで、GIF を作成できます。最初にフレーム数の定数を定義します。後で 2 回必要になるからです。

static void makeAnimatedGif(void) {
    static NSUInteger const kFrameCount = 16;

アニメーションを繰り返す回数を指定するには、プロパティ ディクショナリが必要です。

    NSDictionary *fileProperties = @{
        (__bridge id)kCGImagePropertyGIFDictionary: @{
            (__bridge id)kCGImagePropertyGIFLoopCount: @0, // 0 means loop forever
        }
    };

また、別のプロパティ ディクショナリが必要です。これを各フレームにアタッチして、そのフレームを表示する時間を指定します。

    NSDictionary *frameProperties = @{
        (__bridge id)kCGImagePropertyGIFDictionary: @{
            (__bridge id)kCGImagePropertyGIFDelayTime: @0.02f, // a float (not double!) in seconds, rounded to centiseconds in the GIF data
        }
    };

また、ドキュメント ディレクトリに GIF の URL を作成します。

    NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil];
    NSURL *fileURL = [documentsDirectoryURL URLByAppendingPathComponent:@"animated.gif"];

CGImageDestinationこれで、指定した URL に GIF を書き込むを作成できます。

    CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef)fileURL, kUTTypeGIF, kFrameCount, NULL);
    CGImageDestinationSetProperties(destination, (__bridge CFDictionaryRef)fileProperties);

filePropertiesの最後の引数として渡すことがCGImageDestinationCreateWithURL機能しないことを発見しました。を使用する必要がありますCGImageDestinationSetProperties

これで、フレームを作成して書き込むことができます。

    for (NSUInteger i = 0; i < kFrameCount; i++) {
        @autoreleasepool {
            UIImage *image = frameImage(CGSizeMake(300, 300), M_PI * 2 * i / kFrameCount);
            CGImageDestinationAddImage(destination, image.CGImage, (__bridge CFDictionaryRef)frameProperties);
        }
    }

各フレーム画像とともにフレーム プロパティ ディクショナリを渡すことに注意してください。

指定された数のフレームを正確に追加した後、宛先を確定して解放します。

    if (!CGImageDestinationFinalize(destination)) {
        NSLog(@"failed to finalize image destination");
    }
    CFRelease(destination);

    NSLog(@"url=%@", fileURL);
}

これをシミュレーターで実行すると、デバッグ コンソールから URL をコピーし、ブラウザーに貼り付けて画像を表示できます。デバイスで実行する場合は、Xcode オーガナイザー ウィンドウを使用してデバイスからアプリ サンドボックスをダウンロードし、画像を確認できます。iExplorerまたは、デバイスのファイル システムを直接参照できるようなアプリを使用することもできます。(脱獄は必要ありません。)

iOS 6.1 を実行している iPhone 5 でこれをテストしましたが、コードは iOS 4.0 までさかのぼって動作するはずです。

簡単にコピーできるように、すべてのコードをこの要点に入れました。

于 2013-02-16T23:01:36.163 に答える