读取透明图像 boost.gil C++
reading transparent images boost.gil C++
我有一张透明背景的图片,我想将它复制到另一张图片上 两张图片都是 png 格式 我试过使用 boost::gil::rgba8_image_t,但它仍然复制了灰色背景的透明图片。
这是我用过的
#include <boost/gil.hpp>
#include <boost/gil/extension/io/png.hpp>
#include <boost/gil/extension/numeric/resample.hpp>
#include <boost/gil/extension/numeric/sampler.hpp>
#include <string>
namespace bg = boost::gil;
int main() {
std::string target{"./jail.png"};
std::string picture("./example_in.png");
bg::rgba8_image_t jail;
bg::rgba8_image_t temp;
bg::read_and_convert_image(target, jail, bg::png_tag{});
bg::rgba8_image_t pic(jail.dimensions());
bg::read_and_convert_image(picture, temp, bg::png_tag{});
bg::resize_view(bg::view(temp), bg::view(pic), bg::bilinear_sampler{});
bg::copy_pixels(bg::view(jail), bg::view(pic));
bg::write_view("out.png", bg::view(pic), bg::png_tag{});
}
嗯。阅读这篇文章似乎完全按照你的要求去做:
bg::resize_view(bg::view(temp), bg::view(pic), bg::bilinear_sampler{});
这会使用输入图像的调整大小的视图填充像素。新尺寸与您的监狱尺寸完全匹配。现在:
bg::resize_view(bg::view(temp), bg::view(pic), bg::bilinear_sampler{});
复制 jail
图像中的所有像素。这将替换您刚刚从调整大小的输入图像中填充的任何像素。
你的输出看起来像
注意背景是如何方格的。这是指示透明度的常规模式。那不是灰色。它只是完全透明的空像素。
您可能想要的是保留背景像素。 Boost GIL¹中似乎没有高级像素操作,但您自己编写:
using Img = bg::rgba8_image_t;
using Pix = Img::value_type;
void overlay_combine(Img& pic, Img const& overlay) {
assert(pic.dimensions() == overlay.dimensions());
bg::transform_pixels(
view(pic), const_view(overlay), view(pic),
[](Pix const& a, Pix const& b) {
return get_color(b, bg::alpha_t{})? b : a;
});
}
现在你写 main
如:
int main() {
Img jail, polar;
bg::read_and_convert_image("./jail_PNG16.png", jail, bg::png_tag{});
bg::read_and_convert_image("./polar.png", polar, bg::png_tag{});
Img pic(jail.dimensions());
bg::resize_view(bg::view(polar), bg::view(pic), bg::bilinear_sampler{});
overlay_combine(pic, jail);
bg::write_view("out.png", bg::view(pic), bg::png_tag{});
}
结果是:
你猜猜我从哪里弄来的 polar.png
:)
¹ 参见示例
我有一张透明背景的图片,我想将它复制到另一张图片上 两张图片都是 png 格式 我试过使用 boost::gil::rgba8_image_t,但它仍然复制了灰色背景的透明图片。 这是我用过的
#include <boost/gil.hpp>
#include <boost/gil/extension/io/png.hpp>
#include <boost/gil/extension/numeric/resample.hpp>
#include <boost/gil/extension/numeric/sampler.hpp>
#include <string>
namespace bg = boost::gil;
int main() {
std::string target{"./jail.png"};
std::string picture("./example_in.png");
bg::rgba8_image_t jail;
bg::rgba8_image_t temp;
bg::read_and_convert_image(target, jail, bg::png_tag{});
bg::rgba8_image_t pic(jail.dimensions());
bg::read_and_convert_image(picture, temp, bg::png_tag{});
bg::resize_view(bg::view(temp), bg::view(pic), bg::bilinear_sampler{});
bg::copy_pixels(bg::view(jail), bg::view(pic));
bg::write_view("out.png", bg::view(pic), bg::png_tag{});
}
嗯。阅读这篇文章似乎完全按照你的要求去做:
bg::resize_view(bg::view(temp), bg::view(pic), bg::bilinear_sampler{});
这会使用输入图像的调整大小的视图填充像素。新尺寸与您的监狱尺寸完全匹配。现在:
bg::resize_view(bg::view(temp), bg::view(pic), bg::bilinear_sampler{});
复制 jail
图像中的所有像素。这将替换您刚刚从调整大小的输入图像中填充的任何像素。
你的输出看起来像
注意背景是如何方格的。这是指示透明度的常规模式。那不是灰色。它只是完全透明的空像素。
您可能想要的是保留背景像素。 Boost GIL¹中似乎没有高级像素操作,但您自己编写:
using Img = bg::rgba8_image_t;
using Pix = Img::value_type;
void overlay_combine(Img& pic, Img const& overlay) {
assert(pic.dimensions() == overlay.dimensions());
bg::transform_pixels(
view(pic), const_view(overlay), view(pic),
[](Pix const& a, Pix const& b) {
return get_color(b, bg::alpha_t{})? b : a;
});
}
现在你写 main
如:
int main() {
Img jail, polar;
bg::read_and_convert_image("./jail_PNG16.png", jail, bg::png_tag{});
bg::read_and_convert_image("./polar.png", polar, bg::png_tag{});
Img pic(jail.dimensions());
bg::resize_view(bg::view(polar), bg::view(pic), bg::bilinear_sampler{});
overlay_combine(pic, jail);
bg::write_view("out.png", bg::view(pic), bg::png_tag{});
}
结果是:
你猜猜我从哪里弄来的 polar.png
:)
¹ 参见示例