Lesen transparenter Bilder boost.gil C ++

Jan 17 2021

Ich habe ein Bild mit transparentem Hintergrund und möchte es über ein anderes Bild kopieren. Beide Bilder haben das PNG-Format. Ich habe versucht, boost :: gil :: rgba8_image_t zu verwenden, aber es kopiert stattdessen immer noch das transparente Bild mit grauem Hintergrund. das habe ich benutzt

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

Antworten

3 sehe Jan 17 2021 at 08:20

Mmm. Wenn man dies liest, scheint es genau das zu tun, was man verlangt:

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

Dadurch werden die Pixel mit einer vergrößerten Ansicht Ihres Eingabebildes gefüllt. Die neue Größe entspricht genau der Ihres Gefängnisses. Jetzt:

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

Kopiert alle Pixel aus dem jailBild darüber. Dies ersetzt alle Pixel, die Sie gerade aus dem verkleinerten Eingabebild ausgefüllt haben.

Ihre Ausgabe würde so aussehen

Beachten Sie, wie der Hintergrund kariert ist. Dies ist das herkömmliche Muster zur Anzeige von Transparenz. Das ist nicht grau. Es sind nur leere Pixel mit voller Transparenz.

Was Sie vermutlich wollten, war, die Hintergrundpixel beizubehalten. In Boost GIL¹ scheint es keine Pixeloperation auf hoher Ebene zu geben, aber Sie schreiben sie selbst:

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

Jetzt schreibst du mainwie:

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

Und das Ergebnis ist:

Sie können sich vorstellen, woher ich das habe polar.png:)

¹ siehe zB Wie kombiniere ich Bilder mit Boost Gil?