Change pixel color of QPixmap
-
I have a pixmap, and I would like to change the color of alle pixels with a certain color to another.
QPixmap IconWidget::changeColor(QPixmap& pixmap, QColor to, QColor from) { QImage temp(pixmap.toImage()); for (int y = 0; y < temp.height(); y++) { for (int x= 0; x < temp.width(); x++) { to.setAlpha(temp.pixelColor(x, y).alpha()); from.setAlpha(temp.pixelColor(x, y).alpha()); if (temp.pixelColor(x, y) == from) temp.setPixelColor(x, y, to); } } return QPixmap::fromImage(out); }
This works very well.
But then I found out, that we have to use Qt 5.3. And the functions pixelColor() and setPixelColor() are not introduced before 5.6. So then I thougt to use pixel() and setPixel instead like this:QPixmap IconWidget::changeColor(QPixmap& pixmap, QColor to, QColor from) { QImage temp(pixmap.toImage()); for (int y = 0; y < temp.height(); y++) { for (int x= 0; x < temp.width(); x++) { QColor color(temp.pixel(x, y)); to.setAlpha(color.alpha()); from.setAlpha(color.alpha()); if (color == from) temp.setPixel(x, y, to.rgb()); } } return QPixmap::fromImage(temp); }
And then the pixmaps look like strange boxes. Some of them has some are white, some are black, som have a stranged distorted content.
What should I do?
Is there a better way of doing this? -
I have a pixmap, and I would like to change the color of alle pixels with a certain color to another.
QPixmap IconWidget::changeColor(QPixmap& pixmap, QColor to, QColor from) { QImage temp(pixmap.toImage()); for (int y = 0; y < temp.height(); y++) { for (int x= 0; x < temp.width(); x++) { to.setAlpha(temp.pixelColor(x, y).alpha()); from.setAlpha(temp.pixelColor(x, y).alpha()); if (temp.pixelColor(x, y) == from) temp.setPixelColor(x, y, to); } } return QPixmap::fromImage(out); }
This works very well.
But then I found out, that we have to use Qt 5.3. And the functions pixelColor() and setPixelColor() are not introduced before 5.6. So then I thougt to use pixel() and setPixel instead like this:QPixmap IconWidget::changeColor(QPixmap& pixmap, QColor to, QColor from) { QImage temp(pixmap.toImage()); for (int y = 0; y < temp.height(); y++) { for (int x= 0; x < temp.width(); x++) { QColor color(temp.pixel(x, y)); to.setAlpha(color.alpha()); from.setAlpha(color.alpha()); if (color == from) temp.setPixel(x, y, to.rgb()); } } return QPixmap::fromImage(temp); }
And then the pixmaps look like strange boxes. Some of them has some are white, some are black, som have a stranged distorted content.
What should I do?
Is there a better way of doing this?@Jakob-Clausen said in Change pixel color of QPixmap:
Is there a better way of doing this?
As written in documentation, you should use
QColor::fromRgba()
to not loose alpha channel: -
Like this?
QPixmap IconWidget::changeColor(QPixmap& pixmap, QColor to, QColor from) { QImage temp = pixmap.toImage(); for (int y = 0; y < temp.height(); y++) { for (int x= 0; x < temp.width(); x++) { QColor color = QColor::fromRgba(temp.pixel(x, y)); uint8_t alpha = color.alpha(); to.setAlpha(alpha); from.setAlpha(alpha); uint value = to.rgba(); if (color == from) { temp.setPixel(x, y, value); } } } return QPixmap::fromImage(temp); }
It looks better but still strange.
-
Like this?
QPixmap IconWidget::changeColor(QPixmap& pixmap, QColor to, QColor from) { QImage temp = pixmap.toImage(); for (int y = 0; y < temp.height(); y++) { for (int x= 0; x < temp.width(); x++) { QColor color = QColor::fromRgba(temp.pixel(x, y)); uint8_t alpha = color.alpha(); to.setAlpha(alpha); from.setAlpha(alpha); uint value = to.rgba(); if (color == from) { temp.setPixel(x, y, value); } } } return QPixmap::fromImage(temp); }
It looks better but still strange.
-
Anyone? Is there another way of doing this?
-
Anyone? Is there another way of doing this?
@Jakob-Clausen said in Change pixel color of QPixmap:
Is there another way of doing this?
Without relying on internals? No. You have to go over all pixels, no matter if you're doing it your way or some smarter by relying on internal stuff.
-
@Jakob-Clausen said in Change pixel color of QPixmap:
Is there another way of doing this?
Without relying on internals? No. You have to go over all pixels, no matter if you're doing it your way or some smarter by relying on internal stuff.
@Christian-Ehrlicher Can you see what I am doing wrong. Why is it not working?
-
@Christian-Ehrlicher Can you see what I am doing wrong. Why is it not working?
@Jakob-Clausen said in Change pixel color of QPixmap:
Why is it not working?
Don't know - add some debug output, use a debugger and step trough to see the values. Do what a software developer does in such a case.
-
@Jakob-Clausen said in Change pixel color of QPixmap:
Why is it not working?
Don't know - add some debug output, use a debugger and step trough to see the values. Do what a software developer does in such a case.
@Christian-Ehrlicher I don't understand. How is a debugger going to help me? What do you think I should look for?
-
@Christian-Ehrlicher I don't understand. How is a debugger going to help me? What do you think I should look for?
@Jakob-Clausen said in Change pixel color of QPixmap:
What do you think I should look for?
You should look if e.g. setPixel() is called ...
-
@Jakob-Clausen said in Change pixel color of QPixmap:
What do you think I should look for?
You should look if e.g. setPixel() is called ...
@Christian-Ehrlicher It is being called. If I remove the line, then the picture looks like the original. For me setPixel() is a magic function that should replace one pixel color with another. If it does not, then I am lost.
-
So do you actually use the pixmap returned by the function?
-
Note the caveats mentioned in https://doc.qt.io/qt-5/qimage.html#setPixel :
If the image's format is either monochrome or paletted, the given index_or_rgb value must be an index in the image's color table, otherwise the parameter must be a QRgb value. If position is not a valid coordinate pair in the image, or if index_or_rgb >= colorCount() in the case of monochrome and paletted images, the result is undefined.
So, is your image maybe using a palette? There's more details here: https://doc.qt.io/qt-5/qimage.html#pixel-manipulation
-
@Christian-Ehrlicher It is being called. If I remove the line, then the picture looks like the original. For me setPixel() is a magic function that should replace one pixel color with another. If it does not, then I am lost.
@Jakob-Clausen
As @Christian-Ehrlicher has just asked --- if you think your code is changing the passed-inQPixmap& pixmap
, it is not! -
So do you actually use the pixmap returned by the function?
@Christian-Ehrlicher yes.
-
If I comment out the line setPixel(), then the picture will look like the original:
If I do as described, then it looks like this:
So it is changing the pixelvalues. But it is a little rough on the edges. -
Try to use
setPixelColor(int x, int y, const QColor &color)
. -
Try to use
setPixelColor(int x, int y, const QColor &color)
.@Christian-Ehrlicher If I do that, then it works perfectly. But setPixelColor() is introduced before 5.6, and I am forced to use 5.3.
-
@Christian-Ehrlicher If I do that, then it works perfectly. But setPixelColor() is introduced before 5.6, and I am forced to use 5.3.
@Jakob-Clausen Did you read @kkoehne 's comment? What pixel format do you have?
-
@Jakob-Clausen Did you read @kkoehne 's comment? What pixel format do you have?
@Christian-Ehrlicher QImage::Format_ARGB32_Premultiplied