模糊 QImage alpha 通道

Posted

技术标签:

【中文标题】模糊 QImage alpha 通道【英文标题】:Blur QImage alpha channel 【发布时间】:2016-02-08 13:29:22 【问题描述】:

我正在尝试。我当前的实现使用不推荐使用的 'alphaChannel' 方法并且工作缓慢。

QImage blurImage(const QImage & image, double radius)

  QImage newImage = image.convertToFormat(QImage::Format_ARGB32);

  QImage alpha = newImage.alphaChannel();
  QImage blurredAlpha = alpha;
  for (int x = 0; x < alpha.width(); x++)
  
    for (int y = 0; y < alpha.height(); y++)
    
      uint color = calculateAverageAlpha(x, y, alpha, radius);
      blurredAlpha.setPixel(x, y, color);
    
  
  newImage.setAlphaChannel(blurredAlpha);

  return newImage;

我也尝试使用 QGraphicsBlurEffect 来实现它,但它不会影响 alpha。

什么是的正确方法?

【问题讨论】:

或许值得使用opencv进行图像处理。 【参考方案1】:

我遇到过similar question about pixel read\write access:

    反转循环。图像在内存中布置为连续的行。所以你应该先按高度访问,然后按宽度访问 使用QImage::scanline 访问数据,而不是昂贵的QImage::pixelQImage::setPixel。保证扫描(又名行)中的像素是连续的。

您的代码将如下所示:

for (int ii = 0; ii < image.height(); ii++) 
    uchar* scan = image.scanLine(ii);
    int depth =4;
    for (int jj = 0; jj < image.width(); jj++) 
        //it is in fact an rgba
        QRgb* rgbpixel = reinterpret_cast<QRgb*>(scan + jj*depth);
        QColor color(*rgbpixel);
        int alpha = calculateAverageAlpha(ii, jj, color, image);
        color.setAlpha(alpha);

        //write
        *rgbpixel = color.rgba();
    

您可以进一步优化 alpha 平均值的计算。让我们看一下半径中的像素总和。半径中 (x,y) 处的 alpha 值之和为 s(x,y)。当您在任一方向移动一个像素时,将添加一条线,同时删除一条线。假设你水平移动。如果 l(x,y) 是以 (x,y) 为中心的长度为 2*radius 的垂直线的总和,则您有

  s(x + 1, y) = s(x, y) + l(x + r + 1, y) - l(x - r, y)

这使您可以在第一遍中有效地计算总和矩阵(然后通过除以像素数来求平均值)。

我怀疑这种优化已经在诸如 opencv 之类的库中以更好的方式实现了。因此,如果您想节省时间,我鼓励您使用现有的 opencv 函数。

【讨论】:

以上是关于模糊 QImage alpha 通道的主要内容,如果未能解决你的问题,请参考以下文章

随着 Alpha 的降低,玻璃背景上的绘图文本变得模糊

使用着色器实现粘性效果(处理 3)

flash cs5.5中如何实现边缘模糊遮罩

渐变模糊效果

UIScrollview - 模糊效果 iOS

实现镜面模糊效果