【发布时间】:2014-09-22 13:14:25
【问题描述】:
我想在 QImage 上使用面具。
为了处理面具,我有一个QBitmap。现在我正在寻找一种快速的方法来做这件事:
- 反转掩码的位
- 将蒙版的像素设置为新值
有没有快速的方法来做到这一点?还是只能使用QPainter 对象来修改QBitmap?
问候
【问题讨论】:
我想在 QImage 上使用面具。
为了处理面具,我有一个QBitmap。现在我正在寻找一种快速的方法来做这件事:
有没有快速的方法来做到这一点?还是只能使用QPainter 对象来修改QBitmap?
问候
【问题讨论】:
最好的办法是使用QImage,格式设置为QImage::Format_Mono。通过这种方式,您可以创建一个每像素 1 位的图像,您可以将其用作蒙版。
invertPixels 方法。bits 或scanLine 方法访问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)。要有创意!
【讨论】:
QPainter 的方法setClipRegion() 来设置掩码)
setMask也是一个昂贵的操作,因为QBitmap仍然需要转换成设备依赖QPixmap。因此,也许最好只在掩码更改时更新QPixmap 掩码(除非您为每次绘制都更改它)。也许您可以使用画家的Composition Modes 之一(但似乎不适用于 OpenGL 画家)
Composition Mode 帮助了我。目前我正在使用QImage 的setPixel 方法,但我认为如果我想修改大量像素,位操作会更快。问题是,bits() 只返回一个带有uchar 的指针。你能说我,如何设置像素x的值吗?
getPixel/setPixel 处理图像非常慢。要以 1bpp 格式访问正确的像素,您需要一些位移/掩码魔术。将更新我的答案。