[英]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 次並復制它多次:
buff1
(最初也泄露了)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_cast
由static_assert
保護。 它在邏輯上等同於您的memcpy
類型雙關語。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.