чтение прозрачных изображений boost.gil C ++

Jan 17 2021

У меня есть изображение с прозрачным фоном, и я хочу скопировать его поверх другого изображения, оба изображения в формате 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{});
}

Ответы

3 sehe Jan 17 2021 at 08:20

М-м-м. Читая это, он, кажется, делает именно то, о чем вы его просите:

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:)

¹ см., Например, Как скомбинировать изображения с помощью boost gil?