项目中遇到一个需求,需要将图片中的前景色改成深蓝色#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