Mateusz Kowalczyk
Mateusz Kowalczyk

Reputation: 2066

QImage transform using QGraphicsBlurEffect

I'm looking for a way to apply a blur onto QImage using QGraphicsBlurEffect without doing trickery such as setGraphicsEffect on the label that holds it (this is demonstrated on a different SO question).

Basically, I'm looking for a function blur such that QImage blur(QImage, QGraphicsBlurEffect);

There's a somewhat similar function in existence called qt_blurImage but it's exported in a private header and I'd rather not use it.

Sadly, QImage does not have the setGraphicsEffect

I could of course roll my own blurring function that works on raw data but I'd rather not re-implement something that's already there.

Upvotes: 0

Views: 2955

Answers (2)

PeterSvP
PeterSvP

Reputation: 2046

Let's contribute to this topic. As of Qt 5.3, following function will help you a lot with applying QGraphicsEffect to QImage (and not losing the alpha) - because QWidget::grab() is again in regression.

QImage applyEffectToImage(QImage src, QGraphicsEffect *effect, int extent=0)
{
    if(src.isNull()) return QImage();   //No need to do anything else!
    if(!effect) return src;             //No need to do anything else!
    QGraphicsScene scene;
    QGraphicsPixmapItem item;
    item.setPixmap(QPixmap::fromImage(src));
    item.setGraphicsEffect(effect);
    scene.addItem(&item);
    QImage res(src.size()+QSize(extent*2, extent*2), QImage::Format_ARGB32);
    res.fill(Qt::transparent);
    QPainter ptr(&res);
    scene.render(&ptr, QRectF(), QRectF( -extent, -extent, src.width()+extent*2, src.height()+extent*2 ) );
    return res;
}

Them, using this function to blur your image is straightforward:

QGraphicsBlurEffect *blur = new QGraphicsBlurEffect;
blur->setBlurRadius(8);
QImage source("://img1.png");
QImage result = applyEffectToImage(source, blur);
result.save("final.png");

Of course, you don't need to save it, this was just an example of usefulness. You can even drop a shadow:

QGraphicsDropShadowEffect *e = new QGraphicsDropShadowEffect;
e->setColor(QColor(40,40,40,245));
e->setOffset(0,10);
e->setBlurRadius(50);
QImage p("://img3.png");
QImage res = applyEffectToImage(p, e, 40);

And note the extent parameter, it adds extent number of pixels to all sides of the original image, especially useful for shadows and blurs to not be cut-off.

Upvotes: 5

jmk
jmk

Reputation: 1988

Unfortunately, it looks like the graphics effect API was designed solely for use with QWidget and QGraphicsItem. From a quick look at the 4.7 source (which is what I have on hand), the necessary hooks are all private/internal. Judging from the 5.x source, this is still the case.

It seems like your only choices are the ones you describe: to use QGraphicsEffect with an ugly hack, or implement the blur/effect yourself. (Personally, I would recommend the latter.)

Upvotes: 0

Related Questions