スポンサーリンク

libavifを試す(3) avifファイルを出力

avifを出力するサンプル。

#pragma comment(lib, "avif.lib")

// 4996無効
#define _CRT_SECURE_NO_WARNINGS


#include <iostream>
#include <avif/avif.h>
#include <vector>


// RGBの画像データを作成
std::vector<uint8_t> create_image(int width, int height) {
    std::vector<uint8_t> image(width * height * 3);

    for (int y = 0; y < height; ++y) {
        for (int x = 0; x < width; ++x) {
            int index = (y * width + x) * 3;

            float t = static_cast<float>(y) / (height - 1);

            uint8_t red = static_cast<uint8_t>(255 * (1.0 - t));
            uint8_t green = static_cast<uint8_t>(255 * t);
            uint8_t blue = 0;

            image[index] = red;
            image[index + 1] = green;
            image[index + 2] = blue;
        }
    }

    return image;
}

///////////////////////////////////////////////////
///////////////////////////////////////////////////
///////////////////////////////////////////////////
// libavif で RGBデータをavifデータに変換する


int main()
{
    std::vector<uint8_t> rgb_src;
    int width = 300;
    int height = 200;
    rgb_src = create_image(width, height);

    // RGBデータをエンコードする( YUVデータは入力しないという意味 )
    avifBool encodeYUVDirectly = AVIF_FALSE;


    // 今回はRGBデータを変換するサンプルとする

    if (encodeYUVDirectly == AVIF_FALSE) {

        ////////////////////////////////////////////
        // 変換後のデータの設定を行う
        int yuvDepth = 8;
        avifImage* dst_image = avifImageCreate(width, height, yuvDepth, AVIF_PIXEL_FORMAT_YUV444);

        ////////////////////////////////////////////
        // 変換前データの設定を行う
        avifRGBImage src_Image;
        avifRGBImageSetDefaults(& src_Image, dst_image);
        src_Image.format = AVIF_RGB_FORMAT_RGB;
        src_Image.pixels = rgb_src.data();
        src_Image.rowBytes = width * 3;

        // AVIFはYUV形式で表現するため、まずYUVデータに変換する
        avifResult result = avifImageRGBToYUV(dst_image, &src_Image);
        if (result != AVIF_RESULT_OK) {
            printf("Failed to convert RGB image to YUV: %s\n", avifResultToString(result));
        }
        ////////////////////////////////////////////
        // YUV形式のデータからAVIFのデータを生成
        avifEncoder* encoder = avifEncoderCreate();
        uint32_t quality = 90; // AVIFエンコード品質(0〜100)
        encoder->minQuantizer = AVIF_QUANTIZER_WORST_QUALITY - (uint8_t)(quality * 2.55);
        encoder->maxQuantizer = encoder->minQuantizer;
        ////////////////////////////////////////////

        // エンコード
        avifRWData output = AVIF_DATA_EMPTY;
        result = avifEncoderWrite(encoder, dst_image, &output);
        ////////////////////////////////////////////

        // 作成した画像をファイルに出力
        FILE* oFile = fopen("output.avif", "wb");
        fwrite(output.data, 1, output.size, oFile);
        fclose(oFile);
        ////////////////////////////////////////////
        // 終了処理

        if (dst_image) {
            avifImageDestroy(dst_image);
        }

        avifEncoderDestroy(encoder);
        if (output.data) {
            avifRWDataFree(&output);
        }

    }

    return 0;
}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: