使用QGraphicsBlurEffect的QImage变换

QImage transform using QGraphicsBlurEffect

本文关键字:变换 QImage QGraphicsBlurEffect 使用      更新时间:2023-10-16

我正在寻找一种方法,使用QGraphicsBlurEffectQImage上应用模糊,而不需要在包含它的标签上使用setGraphicsEffect之类的技巧(这在另一个SO问题上演示)。

基本上,我正在寻找一个函数blur,这样QImage blur(QImage, QGraphicsBlurEffect);

有一个有点类似的函数,叫做qt_blurImage,但它是在一个私有标头中导出的,我不想使用它

遗憾的是,QImage没有setGraphicsEffect

当然,我可以使用我自己的模糊函数来处理原始数据,但我宁愿不重新实现已经存在的东西。

让我们为这个主题做贡献。从Qt 5.3开始,以下函数将在很大程度上帮助您将QGraphicsEffect应用于QImage(并且不会丢失alpha),因为QWidget::grab()再次处于回归中。

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

他们,使用这个功能来模糊你的图像很简单:

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

当然,你不需要保存它,这只是一个有用的例子。你甚至可以投下一个阴影:

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

注意范围参数,它将extent像素数添加到原始图像的所有边,特别适用于不截断阴影和模糊。

遗憾的是,API的图形效果似乎是专为与QWidgetQGraphicsItem一起使用而设计的。快速查看4.7源代码(这就是我手头的),必要的钩子都是私有/内部的。从5.x的消息来源来看,情况依然如此。

你唯一的选择似乎是你所描述的:使用QGraphicsEffect进行丑陋的破解,或者自己实现模糊/效果。(就我个人而言,我推荐后者。)