lectura de imágenes transparentes boost.gil C ++

Jan 17 2021

Tengo una imagen con un fondo transparente y quiero copiarla sobre otra imagen. Ambas imágenes tienen formato png. Intenté usar boost :: gil :: rgba8_image_t, pero todavía copia la imagen transparente con un fondo gris. esto es lo que he usado

#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{});
}

Respuestas

3 sehe Jan 17 2021 at 08:20

Mmm. Al leer esto, parece hacer exactamente lo que le pides:

bg::resize_view(bg::view(temp), bg::view(pic), bg::bilinear_sampler{});

Esto llena los píxeles con una vista redimensionada de su imagen de entrada. El nuevo tamaño coincide exactamente con el de su cárcel. Ahora:

bg::resize_view(bg::view(temp), bg::view(pic), bg::bilinear_sampler{});

Copia todos los píxeles de la jailimagen que está encima. Esto reemplaza los píxeles que acaba de completar a partir de la imagen de entrada redimensionada.

Tu salida se vería como

Observe cómo el fondo está a cuadros. Este es el patrón convencional para indicar transparencia. Eso no es gris. Son solo píxeles vacíos con transparencia total.

Lo que presumiblemente quería era mantener los píxeles de fondo. No parece haber una operación de píxeles de alto nivel en Boost GIL¹, pero la escribe usted mismo:

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;
        });
}

Ahora escribe maincomo:

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{});
}

Y el resultado es:

Puedes adivinar de dónde saqué el polar.png:)

¹ ver, por ejemplo, ¿Cómo combinar imágenes con boost gil?