Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QImage::fill(Qt::red) always black?

I am trying to figure out, how QImage works. For start i just want to create a 400x400 pixel QImage and try to fill it red. Well the QImage is filled but black... Also i want to create a monochromatic QImage. One color should be transparent and the other any other (for example: red). How can i do this? I tried it with setcolor, but this doesn't seem to work...

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));
like image 299
honiahaka10 Avatar asked Oct 30 '25 19:10

honiahaka10


2 Answers

Short answer:

Use Format_RGB32 instead of Format_Indexed8 in your QImage constructor.

Detailed answer:

Format_Indexed8 uses the manually defined color table where each index represents a color. You have to create your own color table for your image:

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);

Also you can manually set each index for the current 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)

As you can see, Format_Indexed8 pixel values represent not RGB colors but the index values (which in turn represent the colors you set in the color table).

Format_Mono is another format which also uses the color table (note that only two colors are allowed in it).

Additional answer:

One color should be transparent and the other any other (for example: red).

If I correctly understood you, this code will do what you want:

// 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);
        }
    }
}
like image 94
kefir500 Avatar answered Nov 02 '25 09:11

kefir500


The reason is your QImage::Format you pass to the constructor. Use e.g. QImage::Format_RGB32 to obtain an image accepting colors.

To make usage of your image format, you need to make usage of the setColor method, as shown here for the 8-bit case.

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);

results in

enter image description here

like image 38
Gombat Avatar answered Nov 02 '25 09:11

Gombat