はじめに
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
で動作確認しています。