LoginSignup
0
0

More than 3 years have passed since last update.

AVIFアニメーションを作成する

Last updated at Posted at 2021-04-10

はじめに

AVIFは、静止画だけでなくアニメーションを作成することもできます。
この記事ではアニメーション形式ファイルを作成します。

AVIFファイルの作成で、静止画のAVIFファイル作成方法について、書いています。

環境

AVIFファイルを作成するために、libavifを使用します。

  • Windows 10
  • dmd v2.096.0
  • libavif v0.9.0
  • libaom v2.0.2
  • libdav1d v0.8.2
  • Chrome v89.0.4389.114

AVIFアニメーションは、Chromeで動作確認しています。まだ未対応のブラウザもあるのでご注意ください。

ソースコード

複数のAVIFファイルから、アニメーション形式のAVIFファイルを作成する処理を実装しました。

avifanim.d
/+ dub.sdl:
    name "avifanim"
    dependency "libavif-d" version="~>0.9.0"
    lflags "/NODEFAULTLIB:libcmt.lib"
+/
// dub build --single --build=release avifanim.d
import std.stdio;
import std.string;
import core.stdc.stdio;
import core.stdc.string;
import avif.avif;

pragma(lib, "lib/avif_x64_Release.lib");
pragma(lib, "lib/aom.lib");
pragma(lib, "lib/libdav1d.lib");

ubyte[] loadAvif(string ifile)
{
    auto file = File(ifile, "rb");
    scope(exit) file.close();
    auto size = file.size();
    ubyte[] buf = file.rawRead(new ubyte[size]);
    return ( buf );
}

void saveAvif(string ifile, string ofile)
{
    ubyte[] buf = loadAvif(ifile);
    auto file = File(ofile, "wb");
    scope(exit) file.close();
    file.rawWrite(buf);
}

void saveAnimatedAvif(string[] ifiles, string ofile, ulong timescale)
{
    avifEncoder* encoder = avifEncoderCreate();
    scope(exit) avifEncoderDestroy(encoder);
    encoder.timescale = timescale;
    avifDecoder* decoder = avifDecoderCreate();
    scope(exit) avifDecoderDestroy(decoder);

    foreach ( i, ifile; ifiles ){
        ubyte[] buf = loadAvif(ifile);
        avifDecoderSetIOMemory(decoder, buf.ptr, buf.length);
        avifDecoderParse(decoder);
        while ( avifDecoderNextImage(decoder) == avifResult.AVIF_RESULT_OK ){
            avifEncoderAddImage(encoder, decoder.image, 0, avifAddImageFlags.AVIF_ADD_IMAGE_FLAG_NONE);
        }
    }

    avifRWData avifOutput;
    avifEncoderFinish(encoder, &avifOutput);
    scope(exit) avifRWDataFree(&avifOutput);
    auto f = fopen(ofile.toStringz, "wb");
    scope(exit) fclose(f);
    fwrite(avifOutput.data, 1, avifOutput.size, f);
}

void main(string[] args)
{
    if ( args.length == 3 ){
        saveAvif(args[1], args[2]);
    } else {
        ulong  timescale = 4;   // Hz
        saveAnimatedAvif(args[1 .. $-1], args[$-1], timescale);
    }
}

ソースコード補足

main関数で、timescaleをパラメータとして引き渡しています。
timescaleはアニメーションの表示間隔です。単位はHzです。
実装例では4を設定することで、一秒間に4回画像を切り替えるスピードに設定しました。

コンパイル、実行例

コマンドプロンプト
D:\Dev\Avif> dub build --single --build=release avifanim1.d
Performing "release" build using D:\Dev\dmd2\windows\bin\dmd.exe for x86_64.
avifanim1 ~master: building configuration "application"...
Linking...

D:\Dev\Avif> avifanim out1.avif out2.avif ani.avif

ファイル作成例は、こちらです。
Chromeで動作確認しています。

参考

AVIFファイルの作成

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0