QImage::fill(Qt::red)为什么总是变成黑色?

4

我正在尝试弄清楚QImage的工作原理。首先,我只想创建一个400x400像素的QImage并尝试将其填充为红色。好吧,QImage被填充了,但是却是黑色的... 此外,我想创建一个单色QImage。其中一种颜色应该是透明的,另一种颜色可以是任何其他颜色(例如:红色)。我如何做到这一点?我尝试使用setcolor,但似乎不起作用...

scene = new QGraphicsScene(this);
ui.graphicsView->setScene(scene);
QImage *image = new QImage(400, 400, QImage::Format_Indexed8); //QImage::Format_Mono);
image->fill(Qt::red);
//image->setColor(1, Qt::transparent);
//image->setColor(0, Qt::red);
scene->addPixmap(QPixmap::fromImage(*image));

1
如Qt文档中所述(http://doc.qt.io/qt-4.8/qimage.html),对于QImage:*警告:不支持使用QImage :: Format_Indexed8格式绘制QImage。* Format_Indexed8选项使用颜色表中的索引,其中表是QVector <QRgb>。 - TheDarkKnight
如果您尝试使用 QImage(400, 400, QImage::Format_ARGB32); 会怎样呢? - vahancho
@vahancho:为什么你不看答案? - Gombat
2个回答

6

简短回答:

在您的QImage构造函数中使用Format_RGB32而不是Format_Indexed8

详细回答:

Format_Indexed8使用手动定义的颜色表,其中每个索引表示一种颜色。您必须为您的图像创建自己的颜色表:

QVector<QRgb> color_table;
for (int i = 0; i < 256; ++i) {
    color_table.push_back(qRgb(i, i, i)); // Fill the color table with B&W shades
}
image->setColorTable(color_table);

同时,您还可以手动为当前颜色表设置每个索引:

image->setColorCount(4); // How many colors will be used for this image
image->setColor(0, qRgb(255, 0, 0));   // Set index #0 to red
image->setColor(1, qRgb(0, 0, 255));   // Set index #1 to blue
image->setColor(2, qRgb(0, 0, 0));     // Set index #2 to black
image->setColor(3, qRgb(255, 255, 0)); // Set index #3 to yellow
image->fill(1); // Fill the image with color at index #1 (blue)

如您所见,Format_Indexed8 像素值表示的不是 RGB 颜色,而是索引值(这些索引值再代表你在调色板中设置的颜色)。

Format_Mono 是另一种使用调色板的格式(请注意,该格式只允许两种颜色)。

附加答案:

其中一个颜色应为透明,另一个颜色可以是任意其他颜色(例如红色)。

如果我理解正确,以下代码将满足您的要求:

// Create a 256x256 bicolor image which will use the indexed color table:

QImage *image = new QImage(256, 256, QImage::Format_Mono);

// Manually set our colors for the color table:

image->setColorCount(2);
image->setColor(0, qRgba(255, 0, 0, 255)); // Index #0 = Red
image->setColor(1, qRgba(0, 0, 0, 0));     // Index #1 = Transparent

// Testing - Fill the image with pixels:

for (short x = 0; x < 256; ++x) {
    for (short y = 0; y < 256; ++y) {
        if (y < 128) {
            // Fill the part of the image with red color (#0)
            image->setPixel(x, y, 0);
        }
        else {
            // Fill the part of the image with transparent color (#1)
            image->setPixel(x, y, 1);
        }
    }
}

谢谢!但是我如何使用Format_Mono来实现这个呢?我想要一个红色和透明的图像,而不是黑白的单色图像。 - honiahaka10
这能行吗?我不确定它是否真正透明或者只是因为错误使它看起来像透明... QImage *image = new QImage(400, 400, QImage::Format_Mono); image->setColorCount(2); image->setColor(0, qRgb(255, 0, 0)); image->setColor(1, Qt::transparent); image->fill(1); - honiahaka10
@honiahaka10 看看更新的答案。实际上,我不确定 Format_Mono 是否使用颜色表,但 Format_Indexed8 绝对会使用。 - kefir500
1
用于操作图像像素的函数取决于图像格式。原因是单色和8位图像是基于索引的,并使用颜色查找表。文档上说可以,所以我认为应该可以工作。谢谢! - honiahaka10
@honiahaka10 阅读文档加1。根据你的评论改进了我的答案。 - kefir500

3
原因在于您传递给构造函数的QImage :: Format 。使用例如 QImage :: Format_RGB32 来获取接受颜色的图像。
为了使用您的图像格式,您需要使用setColor方法,如此处所示,对于8位情况。
QImage image(3, 3, QImage::Format_Indexed8);
QRgb value;

value = qRgb(122, 163, 39); // 0xff7aa327
image.setColor(0, value);

value = qRgb(237, 187, 51); // 0xffedba31
image.setColor(1, value);

value = qRgb(189, 149, 39); // 0xffbd9527
image.setColor(2, value);

image.setPixel(0, 1, 0);
image.setPixel(1, 0, 0);
image.setPixel(1, 1, 2);
image.setPixel(2, 1, 1);

结果在

enter image description here


谢谢。使用其他格式它是红色的!但是在单色图像中将颜色更改为例如红色和透明而不是黑白色是否可能? - honiahaka10
你的意思是,你希望红色图像变成透明的吗? - Gombat
不,单色图像只有黑色和白色。我希望我的图片是红色和透明的。 - honiahaka10
这个会起作用吗?我不确定它是否真的是透明的,还是只是一个错误使它看起来是透明的... QImage *image = new QImage(400, 400, QImage::Format_Mono); image->setColorCount(2); image->setColor(0, qRgb(255, 0, 0)); image->setColor(1, Qt::transparent); image->fill(1); - honiahaka10
看起来可以工作。我先尝试添加了一个绿色背景图像,然后在其上方添加了透明的图像。 - Gombat
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接