void colorizeImage( QImage & grayImage, const QColor & color, unsigned int destAlpha ) { // Make sure that the image is Format_ARGB32_Premultiplied if ( grayImage.format() != QImage::Format_ARGB32_Premultiplied ) grayImage = grayImage.convertToFormat( QImage::Format_ARGB32_Premultiplied ); // iterate over all pixels changing the alpha component value unsigned int * data = (unsigned int *)grayImage.bits(); unsigned int pixels = grayImage.width() * grayImage.height(); int red = color.red(), green = color.green(), blue = color.blue(); int source, sourceSat, sourceAlpha; for( unsigned int i = 0; i < pixels; ++i ) { // optimize this loop keeping byte order into account source = data[i]; sourceSat = qRed( source ); int newR = qt_div_255( sourceSat * red ), newG = qt_div_255( sourceSat * green ), newB = qt_div_255( sourceSat * blue ); if ( (sourceAlpha = qAlpha( source )) == 255 ) { // use destAlpha data[i] = qRgba( newR, newG, newB, destAlpha ); } else { // use destAlpha * sourceAlpha product if ( destAlpha < 255 ) sourceAlpha = qt_div_255( destAlpha * sourceAlpha ); data[i] = qRgba( newR, newG, newB, sourceAlpha ); } } }
void forceSetAlphaChannel(QImage &image, const QImage &alphaChannel) { int w = image.width(); int h = image.height(); if (w != alphaChannel.width() || h != alphaChannel.height()) { qWarning("forceSetAlphaChannel: " "Alpha channel must have same dimensions as the target image"); return; } const QImage sourceImage = alphaChannel.convertToFormat(QImage::Format_RGB32); const uchar *src_data = sourceImage.bits(); const uchar *dest_data = image.bits(); for (int y=0; y<h; ++y) { const QRgb *src = (const QRgb *) src_data; QRgb *dest = (QRgb *) dest_data; for (int x=0; x<w; ++x) { int alpha = qGray(*src); int destAlpha = qt_div_255(alpha * 255); //qAlpha(*dest)); *dest = ((destAlpha << 24) | (qt_div_255(qRed(*dest) * alpha) << 16) | (qt_div_255(qGreen(*dest) * alpha) << 8) | (qt_div_255(qBlue(*dest) * alpha))); ++dest; ++src; } src_data += sourceImage.bytesPerLine(); dest_data += image.bytesPerLine(); } }