macでGIFアニメをサクッと作る最高のツール


エンジニアだとMarkdownを使ったりとかSlackでコミュニケーションしたりとか頻繁にしますよね。そこで手軽にアニメーションを共有する手段としてGIFアニメが大変便利なため重宝しますよね!私もGIFアニメよく使うのですが、QuickTime Playerで画面録画をしたmovファイルをGIFに変換するのってみなさんどんな手段でやってますか?

macでGIFアニメを手軽に作るアプリとしては、PicGIFが有名ですが、画像の縦横サイズの編集が手軽にしづらかったり、繰り返し再生回数を指定できなかったり(とりわけ無限ループにできない)、各コマのalignmentが調整できなかったり、GIFのトリミングができなかったり、痒いところに手が届かないと感じていました。また、Effectや文字列追加機能は不要だと思っていたため、必要十分な機能のアプリを作ることにしました。

GIFlash


特徴

  1. 複数のコマ画像をインポートしてパラパラ漫画を作れる
  2. 動画からコマ画像を切り出してインポートできる
  3. 繰り返し再生(ループ)の回数を指定できる
  4. GIFアニメのサイズの変更が容易
    (アスペクト比をロックして拡大縮小できる)
  5. サイズの異なるリソースを用いる場合、中央揃えや右寄せ、上寄せなど配置の指定ができる
  6. 背景色の指定ができる(透明も可)
  7. 既存のGIFアニメのトリミングができる
  8. 編集中の各コマをPNGとして出力できる

技術的な話

NSImageの配列からGIFを作って保存する方法

  • CGImageDestinationなんたらをつかっていく。
  • 繰り返し回数は0を指定すると無限ループになる
  • kCGImagePropertyGIFDelayTimeという属性とkCGImagePropertyGIFUnclampedDelayTimeという属性があるが、前者だとフレーム間隔の最小が100msまでしか指定できない。後者を選ぶともっと間隔を短くできる。
import Cocoa
import ImageIO

var frames = [CGImage]() // フレームを追加しておく

func generateGif(_ saveURL: URL, // NSSavePanelとかでユーザに保存場所を指定させる
                 _ loopCount: Int, // 繰り返し再生回数
                 _ interval: Float, // フレーム間隔
                 successHandler: () -> Void,
                 failureHandler: () -> Void) {
    guard 0 < frames.count,
          let gif = CGImageDestinationCreateWithURL(saveURL as CFURL, kUTTypeGIF, frames.count, nil)
    else { return failureHandler() }
    // 繰り返し再生回数の指定
    let props = [
        (kCGImagePropertyGIFDictionary as String) : [(kCGImagePropertyGIFLoopCount as String) : loopCount]
    ]
    CGImageDestinationSetProperties(gif, props as CFDictionary)
    // フレーム間隔の指定
    let frameProps = [
        (kCGImagePropertyGIFDictionary as String) : [(kCGImagePropertyGIFUnclampedDelayTime as String) : interval]
    ]
    // フレームを追加していく
    frames.forEach { (frame) in
        CGImageDestinationAddImage(gif, frame, frameProps as CFDictionary)
    }
    // 出力する
    if CGImageDestinationFinalize(gif) {
        successHandler()
    } else {
        failureHandler()
    }
}

そのほかハマったところ

リンク

  • GIFLash 使ってみてのコメント待ってます🙏