簡體   English   中英

Boost::GIL:使用 alpha 通道讀取 *.png 圖像缺少抗鋸齒

[英]Boost::GIL: reading *.png image with alpha channel is missing antialiasing

我正在使用提升 1.74。

所以,沒有異常捕獲和 rest 東西我的實際代碼看起來像:

typedef std::vector<int32_t> FlatINT32TArr;

using PreviewImageT = bg::rgba8_image_t;
using PreviewViewT = bg::rgba8_view_t;
using PreviewPixelT = bg::rgba8_pixel_t;

void read_pixel_arr(FlatINT32TArr r_preview_flat_arr, const std::wstring& filepath)
{
  std::ifstream byte_stream(filepath, std::ios::binary);

  PreviewImageT image;

  bg::read_and_convert_image(
    byte_stream, image, bg::image_read_settings<bg::png_tag>());

  const int image_width = (int)image.width();
  const int image_height = (int)image.height();

  const int preview_pixel_count = image_width * image_height;

  PreviewViewT preview_view;
  PreviewPixelT* buff1 = new PreviewPixelT[preview_pixel_count];
  preview_view = bg::interleaved_view(
    image_width, image_height, buff1,
    image_width * sizeof(PreviewPixelT));

  bg::copy_and_convert_pixels(
    bg::flipped_up_down_view(const_view(image)), preview_view);

  r_preview_flat_arr = FlatINT32TArr(preview_pixel_count);
  memcpy(
    &r_preview_flat_arr[0],
    &preview_view[0],
    sizeof(PreviewPixelT) * preview_pixel_count
  );
}

它讀取 *.png 圖像文件並將其轉換為 int32_t 數組。 (然后使用該數組生成 OpenGL 紋理)。

所以,原始圖像文件是:

原來的

它是從 Adobe Illustrator 導出的,帶有 alpha 通道,去隔行掃描。

在這里,我遇到了一些我無法解決的問題:

  • 二次抽樣。

在此處輸入圖像描述 - 這是結果。 如您所見,圖像與樓梯一樣多,為什么? 如何解決?

  • 交錯。

在此處輸入圖像描述 - 這是結果。 如您所見,從圖像底部到頂部是否還有一行。 暫時通過導出去隔行圖像來解決它,但這不是最好的方法。 如何使用 gil 解決它?

另一項測試:原始測試(帶有 alpha 通道漸變):

在此處輸入圖像描述

結果:

在此處輸入圖像描述

顯示的轉換似乎有問題。

當我將預覽數據保存為 PNG 時:

bg::write_view("output.png", preview_view, bg::png_tag{});

我得到了預期的 output:

在此處輸入圖像描述

這就是您在平面 int32 向量中復制它時的預覽緩沖區 ( buff1 )。

另請注意

  • 返回參數是按值傳遞的,這意味着它實際上不會被read_pixel_arr更改(添加&用於傳遞引用)
  • 存在 memory 泄漏,因為buff1從未被釋放。 下面,我用unique_ptr修復了它。

住在科利魯

void read_pixel_arr(FlatINT32TArr& r_preview_flat_arr, std::string filepath) {
    std::ifstream byte_stream(filepath, std::ios::binary);

    bg::image_read_settings<bg::png_tag> settings;
    //settings._read_transparency_data = true;

    PreviewImageT image;
    bg::read_and_convert_image(byte_stream, image, settings);

    auto width   = image.width();
    auto height  = image.height();
    auto npixels = width * height;

    auto buff1 = std::make_unique<PreviewPixelT[]>(npixels);
    auto preview_view = bg::interleaved_view(
            width, height, buff1.get(),
            width * sizeof(PreviewPixelT));
    assert(buff1.get() == &preview_view[0]); // checking understanding

    bg::copy_and_convert_pixels(
            bg::flipped_up_down_view(const_view(image)), preview_view);

    r_preview_flat_arr = FlatINT32TArr(npixels);
    memcpy(r_preview_flat_arr.data(), 
           buff1.get(),
           sizeof(PreviewPixelT) * npixels);

    bg::write_view("output.png", preview_view, bg::png_tag{});
}

int main() {
    FlatINT32TArr v(1 << 20);
    read_pixel_arr(v, "sample.png");
}

大大簡化

使用read_image_info您可以避免分配緩沖區 3 次並復制它多次:

  1. 用於圖像緩沖區(僅用於復制和檢測寬度/高度)
  2. 對於buff1 (最初也泄露了)
  3. 對於平面數組( std::vector

相反,讓我們從文件信息中檢測維度,並直接讀入平面數組:

auto flatvector_view(FlatINT32TArr& v, long width) {
    return bg::interleaved_view(
       width, v.size()/width,
       reinterpret_cast<PreviewPixelT*>(v.data()),
       width * sizeof(PreviewPixelT));
}

long read_pixel_arr(FlatINT32TArr& r_pixeldata, std::string filepath) {
    bg::image_read_settings<bg::png_tag> settings;
    auto info   = bg::read_image_info(filepath, settings);
    auto width  = info._info._width;
    auto height = info._info._height;
    r_pixeldata.resize(width * height);

    bg::read_and_convert_view(filepath,
        bg::flipped_up_down_view(flatvector_view(r_pixeldata, width)),
        settings);

    return width;
}

int main() {
    FlatINT32TArr v;
    auto width = read_pixel_arr(v, "sample.png");

    bg::write_view("output.png", flatvector_view(v, width), bg::png_tag{});
}

請注意, reinterpret_caststatic_assert保護。 它在邏輯上等同於您的memcpy類型雙關語。


暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM