【问题标题】:how to modify pixels of QBitmap如何修改QBitmap的像素
【发布时间】:2014-09-22 13:14:25
【问题描述】:

我想在 QImage 上使用面具。 为了处理面具,我有一个QBitmap。现在我正在寻找一种快速的方法来做这件事:

  1. 反转掩码的位
  2. 将蒙版的像素设置为新值

有没有快速的方法来做到这一点?还是只能使用QPainter 对象来修改QBitmap

问候

【问题讨论】:

    标签: qt mask qimage qpixmap


    【解决方案1】:

    最好的办法是使用QImage,格式设置为QImage::Format_Mono。通过这种方式,您可以创建一个每像素 1 位的图像,您可以将其用作蒙版。

    1. 要反转像素,请使用invertPixels 方法。
    2. 可以使用bitsscanLine 方法访问QImage 位。

    要将QImage 用作掩码,您必须先将其转换为QPixmap

    QPixmap mask = QPixmap::fromImage(img);
    painter.setClipRegion(QRegion(mask));
    

    由于QImage::Format_Mono 首先以 8 个像素/字节对像素 MSB 进行编码(意味着第一个像素将存储在第一个字节的最高有效位中),因此您需要一些位魔术才能访问给定的正确位x/y 位置:

    int GetPixel(const QImage& img, const int x, const int y) const
    {
        const uchar mask = 0x80 >> (x % 8);
        return img.scanLine(y)[x / 8] & mask ? 1 : 0;
    }
    
    void SetPixel(QImage& img, const int x, const int y, const int pixel)
    {
        const uchar mask = 0x80 >> (x % 8);
        if (pixel)
            img.scanLine(y)[x / 8] |= mask;
        else
            img.scanLine(y)[x / 8] &= ~mask;
    }
    

    当然,当您在同一行上处理大量像素时,不要使用像 SetPixel 这样的函数,因为您不想为每个像素查找 scanLine(y)。要有创意!

    【讨论】:

    • 谢谢。我也有这个想法。但是我每次都必须将 QImage 转换为 QBitmap,以将其用作掩码。或者我怎样才能使用 Qimage 作为面具? (及时我使用QPainter 的方法setClipRegion() 来设置掩码)
    • 问题是setMask也是一个昂贵的操作,因为QBitmap仍然需要转换成设备依赖QPixmap。因此,也许最好只在掩码更改时更新QPixmap 掩码(除非您为每次绘制都更改它)。也许您可以使用画家的Composition Modes 之一(但似乎不适用于 OpenGL 画家)
    • Composition Mode 帮助了我。目前我正在使用QImagesetPixel 方法,但我认为如果我想修改大量像素,位操作会更快。问题是,bits() 只返回一个带有uchar 的指针。你能说我,如何设置像素x的值吗?
    • 使用getPixel/setPixel 处理图像非常慢。要以 1bpp 格式访问正确的像素,您需要一些位移/掩码魔术。将更新我的答案。
    • 现在完美运行。我只在 Qt 5.3 中遇到了 QRegion 的问题。在那里我无法使用 QPixmap 创建区域。但我可以从 QImage (QBitmap ::fromImage) 创建一个 QBitmap
    猜你喜欢
    • 1970-01-01
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多