项目中遇到一个需求,需要将图片中的前景色改成深蓝色#202189,背景色为白色。
方法1: 在原图img1叠一个深蓝色的矩形
1 2 3 4 5
| QImage img2 = img1; QPainter painter(&img2); painter.setCompositionMode(QPainter::CompositionMode_SourceIn); painter.fillRect(img2.rect(), QColor(“#202189”)); painter.end();
|
此方法仅对有alpha通道的图片有效。
可以用下面的方法检测是否使用了alpha通道。
1 2 3 4 5 6 7 8 9 10 11
| bool useAlpha = false; { const uchar* pixelData = img1.bits(); int bytes = img1.byteCount(); for (const QRgb* pixel = reinterpret_cast<const QRgb*>(pixelData); bytes > 0; pixel++, bytes -= sizeof(QRgb)){ if (qAlpha(*pixel) != UCHAR_MAX) { useAlpha = true; break; } } }
|
方法2:修改每个像素点的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| void recolor(QImage *image, const QColor &foreground, const QColor &background) { if (image->format() != QImage::Format_ARGB32_Premultiplied) { *image = image->convertToFormat(QImage::Format_ARGB32_Premultiplied); } Q_ASSERT(image->format() == QImage::Format_ARGB32_Premultiplied); const float scaleRed = background.redF() - foreground.redF(); const float scaleGreen = background.greenF() - foreground.greenF(); const float scaleBlue = background.blueF() - foreground.blueF(); for (int y=0; y<image->height(); y++) { QRgb *pixels = reinterpret_cast<QRgb*>(image->scanLine(y)); for (int x=0; x<image->width(); x++) { const int lightness = qGray(pixels[x]); pixels[x] = qRgba(scaleRed * lightness + foreground.red(), scaleGreen * lightness + foreground.green(), scaleBlue * lightness + foreground.blue(), qAlpha(pixels[x])); } } }
|
使用recolor:
1 2
| QImage img1("D:/1.png"); recolor(&img1, QColor("#202189"), QColor("#FFFFFF"));
|
Reference