Important: Please read the Qt Code of Conduct -

Blend small image over larger image

  • I have a 3840×720 background image (a static map) with many small images (e.g. 86×86) positioned overtop, highlighting specific buildings. These small images dynamically show and hide. I'd like to screen blend these images when displayed.

    If I fill the Blend to the background, then the tiny highlight image is scaled to fill the entire map:

    Image {
        source: 'images/map-bg'
        Image { id:highlight-a; source:'images/highlight-a'; x:1230; y:470; visible:false }
        Blend { anchors.fill:parent; source:parent; foregroundSource:highlight-a; mode:'screen' }

    If I instead fit the Blend to the highlight image, then a full copy of the background map is scaled down to fit the size of the highlight image:

    Image {
        source: 'images/map-bg'
        Image { id:highlight-a; source:'images/highlight-a'; x:1230; y:470; visible:false }
        Blend { anchors.fill:highlight-a; source:parent; foregroundSource:highlight-a; mode:'screen' }

    Is there a way to have the Blend effect read the region of the source image that the foreground is over, and only use that?

    The only workarounds I can think of are to either (a) make a 3840×720 with all items in it and blend that huge (mostly empty) image, wasting perf, or (b) use item layers with a custom shader for screen blend mode, with some code (that I don't know how to write) that would calculate and sample just the region I want for the underlying image.

    This seems to be intimately related to this StackOverflow question I wrote up when I ran into a similar problem last year. That question remains unanswered.

  • @6thC Nope, but thanks! The core issue is different image sizes. The first does not address that problem, the second is QPainter (not generic QML image composition).

  • @Phrogz

    Sorry, my bad. I didn't realize Blend was not yours. And. Wow, that Blend is pretty neat...

    I'm not sure how really in QML, but I know I load QPixMaps and that has scaled, which I use for my Splash... while I was doing that I did notice ::copy ... what about generating a QPixmap of the region you require to blend, blend with that and overlay? If I understand correctly...

    To get into QML, maybe use a QQuickImageProvider or -- this bit I've not needed / tested or used.

    In c++ this clips 500*500 for me...

     const QImage image(":/images/image.png");
        // imageQPainter::SmoothPixmapTransform
        QPixmap pixmap = QPixmap::fromImage(image);
    //        ,Qt::AspectRatioMode::KeepAspectRatio
    //      ,Qt::SmoothTransformation);
        const auto rect = QRect(0,0, 500, 500);
        const QPixmap pixmapCopy = pixmap.copy(rect);

    I don't use copy, I use the commented out scaled to reduce from a 3k * 3k source myself, that's just for my splash screen, used like:

    QSplashScreen *splash = new QSplashScreen(pixmap);

    If I do

    QSplashScreen *splash = new QSplashScreen(pixmapCopy);

    I just get the first 500*500

    If this isn't helping I can just shutup too... just figure no one else seems to. I can at least try?

Log in to reply