PDA

View Full Version : QBitmap color inversion



jkv
18th July 2009, 13:48
I have a simple bitmap image (.xpm format, though it could be any grayscale) drawn in some other tool so that black pixels are meant to be transparent and white opaque as follows


/* XPM */
static char *hex[]={
"20 16 2 1",
". c #000000",
"# c #ffffff",
".....##########.....",
"....############....",
"...##############...",
"...##############...",
"..################..",
"..################..",
".##################.",
"####################",
"####################",
".##################.",
"..################..",
"..################..",
"...##############...",
"...##############...",
"....############....",
".....##########....."};

First I load the image as QBitmap, then draw to another QPixmap


QBitmap bitmap("mono.xpm");

QPixmap pixmap(bitmap.size());
pixmap.fill(Qt::green);
QPainter painter(&pixmap);
painter.setPen(Qt::red); // 1-bits in bitmap red
painter.setBackgroundMode(Qt::TransparentMode); // 0-bits in bitmap transparent
painter.drawPixmap(0,0,bitmap);

Now when I draw the pixmap later, colors are inverted so that what originally was "white" in loaded bitmap is green and "black" is red -- contrary to what I expected.

Now I did some source reading and found out that function QBitmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags) defined in src/gui/image/qbitmap.cpp (Qt 4.5.2) actually does invert the colors and as far as I can tell is the reason behind this behaviour


--snip
// make sure image.color(0) == Qt::color0 (white)
// and image.color(1) == Qt::color1 (black)
const QRgb c0 = QColor(Qt::black).rgb();
const QRgb c1 = QColor(Qt::white).rgb();
if (img.color(0) == c0 && img.color(1) == c1) {
img.invertPixels();
img.setColor(0, c1);
img.setColor(1, c0);
}
--snip>

So I know of the reason but not of WHY it does that... Is this maybe some axiomatic idea that "white" pixels represent transparent areas in mono images and "black" opaque? I don't do much image processing... but somehow it doesn't seem "right".

Anyone who might have some clarification to this? Thanks!

wysota
19th July 2009, 21:49
In general we (humans) consider white to be the natural colour of paper and black to be the "ink" (opaque colour). QBitmap stores bits. Value 0 represents "empty" and value 1 represents "opaque". Black corresponds to 0 (#000000), white corresponds to 1 (#FFFFFF) so if the engine receives an "inverted" picture, it inverts it back so that you can see your "white is paper" despite the bit values really used by QBitmap. In other words the conversion tells the bitmap that although it sees black, it should show white and the other way round.

jkv
20th July 2009, 12:21
Thanks! Thinking it as paper/ink makes a lot of sense. And me fool thought 1 is a 1 always :rolleyes: