C++ Boost::GIL:读取带有alpha通道的*.png图像缺少抗锯齿
我用的是boost 1.74 因此,毫无例外,捕获和rest内容我的实际代码如下所示:C++ Boost::GIL:读取带有alpha通道的*.png图像缺少抗锯齿,c++,boost,boost-gil,C++,Boost,Boost Gil,我用的是boost 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
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
);
}
typedef std::vector FlatINT32TArr;
使用PreviewImageT=bg::rgba8_image_t;
使用PreviewViewT=bg::rgba8\u view\t;
使用PreviewPixelT=bg::rgba8_pixel_t;
无效读取像素阵列(FlatINT32TArr r r\u预览\u flat\u阵列,常数std::wstring&filepath)
{
std::ifstream字节流(文件路径,std::ios::binary);
预览图像;
bg::读取和转换图像(
字节\流,图像,背景::图像\读取\设置();
常量int image_width=(int)image.width();
常量int image_height=(int)image.height();
const int preview_pixel_count=图像宽度*图像高度;
预览视图t预览视图;
PreviewPixelT*buff1=新的PreviewPixelT[预览像素数];
预览\u视图=bg::交错\u视图(
图像宽度,图像高度,buff1,
图像宽度*大小(预览像素带);
bg::复制和转换像素(
背景::翻转上下视图(常量视图(图像)),预览视图);
r\u预览\u平面\u arr=FlatINT32TArr(预览\u像素\u计数);
memcpy(
&r_预览_平面_arr[0],
&预览视图[0],
sizeof(预览像素)*预览像素数
);
}
它读取*.png图像文件并将其转换为int32_t数组。(然后使用该数组生成OpenGL纹理)
因此,原始图像文件是:
它是从AdobeIllustrator中导出的,带有alpha通道,已解交错
这里有几个我无法解决的问题:
- 二次抽样
- 交错
显示的转换后,似乎出现了问题 当我将预览数据保存为PNG时:
bg::write_view("output.png", preview_view, bg::png_tag{});
我得到了预期的输出:
这就是预览缓冲区(buff1
),与在平面int32向量中复制它时完全相同
也请注意
- 返回参数是按值传递的,这意味着它实际上不会被
更改(添加了read\u pixel\u arr
,用于按引用传递)&
- 内存泄漏,因为从未释放过
。下面,我用一个buff1
修复了它唯一的\u 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");
}
请注意,reinterpret\u cast
由static\u assert
保护。它在逻辑上等同于memcpy
类型双关语
我不认为这就是别名。你是说它被像素化了?@sehe,是的,像素化了。看起来圆形边框上的像素缺少alpha通道。如您所见,结果线宽比原始图像稍高。由于某些原因,在原始图像像素被抗锯齿的区域(形状边界),alpha通道值被钳制为1.0f。Smth类似:
result\u alpha=(原始\u alpha>0.0f)?1.0f:0.0f
是。当然,我只是缺少了问题描述示例代码中的符号,它看起来像mem leak;)不幸的是,和以前一样,我无法直接绘制代码,我所能做的就是生成像素的numpy数组并从中设置图标像素。在这里,我仅限于数据类型的使用(如您所见,我需要int32_t 1D数组)。但你的帖子也很有用,因为它展示了更方便、更正确的实现方式,谢谢!当然我只是想帮助您认识到问题存在于所示代码之外。如果你无法找到更深层次的原因,你可以发布其他问题。[我并没有假设您的真实代码中缺少了符号,因为您肯定会看到不同的症状。完全可以肯定的是,内存泄漏与此无关,但这可能也不太相关]对于文档(以及boost
)来说,情况非常糟糕。我有一个疯狂的想法,看看read\u和\u convert\u view
在代码中的用法。是否可以使用smth(如bg::resize_view
)来生成预览(图像的较小版本)?例如,我有500+8K图像的数据集,我需要为它们生成预览。以前的实现效果很好,它是<30秒(从SSD运行),但我认为它可以更好。是的。[Paul] [Puff]严肃地说,如果你想对它进行评论,可以考虑把它放在可能偏离主题的地方,但是看起来像“代码> Boo::吉尔< /COD>——它被抛弃的项目。最有趣的是,它是唯一一个图像处理库,它粘合了一些本机格式库,并允许从流中执行io(例如,OpenCV不允许这样做,OpenImageIO允许这样做,但以非常有限的方式,并非所有图像类型都允许这样做)
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{});
}