Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Boost::GIL:读取带有alpha通道的*.png图像缺少抗锯齿_C++_Boost_Boost Gil - Fatal编程技术网

C++ Boost::GIL:读取带有alpha通道的*.png图像缺少抗锯齿

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

我用的是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 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通道,已解交错

这里有几个我无法解决的问题:

  • 二次抽样
-这是结果。正如你们所看到的,这幅图像的别名和楼梯一样多,为什么?如何解决

  • 交错
-这是结果。正如您所看到的,从图片底部到顶部还有一行吗。暂时通过导出隔行扫描图像解决了这个问题,但这不是最好的方法。如何使用gil解决它

还有一个测试: 原始通道(具有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{});
}