QT4如何模糊QPixmap图像?

Ast*_*tor 5 graphics qt qt4 effects

QT4如何模糊QPixmap图像?

我正在寻找类似以下之一:

Blur(pixmap); 
painter.Blur(); 
painter.Blur(rect);
Run Code Online (Sandbox Code Playgroud)

做这个的最好方式是什么?

小智 9

1)声明外部QT例程:

QT_BEGIN_NAMESPACE
  extern Q_WIDGETS_EXPORT void qt_blurImage( QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0 );
QT_END_NAMESPACE
Run Code Online (Sandbox Code Playgroud)

2)使用:

  extern QImage srcImg;//source image
  QPixmap pxDst( srcImg.size() );//blurred destination
  pxDst.fill( Qt::transparent );
  {
    QPainter painter( &pxDst );
    qt_blurImage( &painter, srcImg, 2, true, false );//blur radius: 2px
  }
Run Code Online (Sandbox Code Playgroud)


And*_*ewS 6

方法1a:抓住原始位并自己完成.您需要充分熟悉位图和模糊算法以自己实现模糊.如果你想要那种精确度,这就是你要走的路.

QImage image = pixmap.toImage();
if (image.format() != QImage::Format_RGB32)
     image = image.convertToFormat(QImage::Format_RGB32);
uchar* bits = image.bits();
int rowBytes = image.bytesPerLine();
DoMyOwnBlurAlgorithm(bits, image.width(), image.height(), rowBytes);
return QPixmap::fromImage(image);
Run Code Online (Sandbox Code Playgroud)

方法1b:谁需要原始位?您可以使用image.pixel(x,y)和image.setPixel(x,y,color)代替.这不会像1a那么快,但它应该更容易理解和编码.

QImage image = pixmap.toImage();
QImage output(image.width(), image.height(), image.format());
for (int y=0; y<image.height(); ++y)
   for (int x=0; x<image.width(); ++x)
      output.setPixel(getBlurredColor(image, x, y));
return output;
Run Code Online (Sandbox Code Playgroud)

方法2:通过小部件或场景使用QGraphicsBlurEffect.这里的代码使用标签小部件:

QPixmap BlurAPixmap(const QPixmap& inPixmap)
{
    QLabel* label = new QLabel();
    label->setPixmap(inPixmap);
    label->setGraphicsEffect(new QGraphicsBlurEffect());
    QPixmap output(inPixmap.width(), inPixmap.height());
    QPainter painter(&output);
    label->render(&painter);
    return output;
}
Run Code Online (Sandbox Code Playgroud)

根据需要调整.例如,我假设默认的图形模糊效果是可以接受的.我在我的项目中使用方法2.


liu*_*rry 5

看看这个:

#include <QtGui/QApplication>
#include <QImage>
#include <QPixmap>
#include <QLabel>

QImage blurred(const QImage& image, const QRect& rect, int radius, bool alphaOnly = false)
{
    int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
    int alpha = (radius < 1)  ? 16 : (radius > 17) ? 1 : tab[radius-1];

    QImage result = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
    int r1 = rect.top();
    int r2 = rect.bottom();
    int c1 = rect.left();
    int c2 = rect.right();

    int bpl = result.bytesPerLine();
    int rgba[4];
    unsigned char* p;

    int i1 = 0;
    int i2 = 3;

    if (alphaOnly)
        i1 = i2 = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3);

    for (int col = c1; col <= c2; col++) {
        p = result.scanLine(r1) + col * 4;
        for (int i = i1; i <= i2; i++)
            rgba[i] = p[i] << 4;

        p += bpl;
        for (int j = r1; j < r2; j++, p += bpl)
            for (int i = i1; i <= i2; i++)
                p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
    }

    for (int row = r1; row <= r2; row++) {
        p = result.scanLine(row) + c1 * 4;
        for (int i = i1; i <= i2; i++)
            rgba[i] = p[i] << 4;

        p += 4;
        for (int j = c1; j < c2; j++, p += 4)
            for (int i = i1; i <= i2; i++)
                p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
    }

    for (int col = c1; col <= c2; col++) {
        p = result.scanLine(r2) + col * 4;
        for (int i = i1; i <= i2; i++)
            rgba[i] = p[i] << 4;

        p -= bpl;
        for (int j = r1; j < r2; j++, p -= bpl)
            for (int i = i1; i <= i2; i++)
                p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
    }

    for (int row = r1; row <= r2; row++) {
        p = result.scanLine(row) + c2 * 4;
        for (int i = i1; i <= i2; i++)
            rgba[i] = p[i] << 4;

        p -= 4;
        for (int j = c1; j < c2; j++, p -= 4)
            for (int i = i1; i <= i2; i++)
                p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
    }

    return result;
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QLabel label;
    QImage image("image.png");
    image =  blurred(image,image.rect(),10,false);
    label.setPixmap(QPixmap::fromImage(image));
    label.show();

    return a.exec();
}
Run Code Online (Sandbox Code Playgroud)


Пет*_*ров 5

让我们为这个主题做出贡献。从 Qt 5.3 开始,以下函数将帮助您将 QGraphicsEffect 应用于 QImage(并且不会丢失 alpha)

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;
}
Run Code Online (Sandbox Code Playgroud)

他们,使用此功能模糊您的图像很简单:

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

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

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);
Run Code Online (Sandbox Code Playgroud)

并注意范围参数,它extent为原始图像的所有边增加了像素数,对于阴影和模糊不被截断特别有用。


gsp*_*spr 0

高斯模糊是创建模糊效果的简单方法。

编辑:瞧,我遇到了 Qt 的QGraphicsBlurEffect。在 Qt 4.6 中引入,它似乎完全符合您的要求。