4

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));
honiahaka10
  • 772
  • 4
  • 9
  • 29
  • 1
    As stated in the [Qt docs](http://doc.qt.io/qt-4.8/qimage.html) for QImage: *Warning: Painting on a QImage with the format QImage::Format_Indexed8 is not supported.* The Format_Indexed8 option, uses an index into a colour table, where the table is QVector – TheDarkKnight Sep 17 '15 at 08:06
  • What if you try `QImage(400, 400, QImage::Format_ARGB32);`? – vahancho Sep 17 '15 at 08:09
  • @vahancho: y u no read answers? – Gombat Sep 17 '15 at 08:19

2 Answers2

6

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);
        }
    }
}
kefir500
  • 4,184
  • 6
  • 42
  • 48
  • Thank you! But how can I do this with `Format_Mono`? Instead of a monochromatic image with black and white i want one in red and transparent. – honiahaka10 Sep 17 '15 at 08:20
  • Would this work? Im not sure, wether it is really transparent or there is just an error making it seem to be transparent... ` 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 Sep 17 '15 at 08:37
  • @honiahaka10 See the updated answer. Actually, I'm not sure if `Format_Mono` uses the color table, but `Format_Indexed8` definitely does. – kefir500 Sep 17 '15 at 08:47
  • 1
    "The functions used to manipulate an image's pixels depend on the image format. The reason is that monochrome and 8-bit images are index-based and use a color lookup table" The doc says it does, so i think it should work. Thank you! – honiahaka10 Sep 17 '15 at 08:54
  • @honiahaka10 +1 for reading the docs. Improved my answer considering your comment. – kefir500 Sep 17 '15 at 09:14
3

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

Gombat
  • 1,994
  • 16
  • 21
  • Thanks with other formats it is red! But is it possible to change the color in a monochromatig image to for example red and transparent instead of black and white? – honiahaka10 Sep 17 '15 at 08:09
  • you mean, you want the red image to be transparent? – Gombat Sep 17 '15 at 08:11
  • No, a monochromatic image would have the colors black and white. I want my image to have the colors red AND transparent. – honiahaka10 Sep 17 '15 at 08:21
  • simply use the ARGB format and set some parts of the image to fully transparent – Gombat Sep 17 '15 at 08:28
  • Would this work? Im not sure, wether it is really transparent or there is just an error making it seem to be transparent... ` 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 Sep 17 '15 at 08:35
  • It seems to work. I tested it adding a green background image first and adding on top the transparent one. – Gombat Sep 17 '15 at 08:44
  • Thank You for checking this! – honiahaka10 Sep 17 '15 at 08:55