summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/image/qimage.cpp95
-rw-r--r--src/gui/image/qimage.h4
-rw-r--r--src/plugins/imageformats/ico/qicohandler.cpp2
3 files changed, 32 insertions, 69 deletions
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 99d64737c5..3ddc52bed4 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -4410,99 +4410,61 @@ bool QImage::isDetached() const
/*!
- \obsolete
Sets the alpha channel of this image to the given \a alphaChannel.
- If \a alphaChannel is an 8 bit grayscale image, the intensity values are
- written into this buffer directly. Otherwise, \a alphaChannel is converted
- to 32 bit and the intensity of the RGB pixel values is used.
-
- Note that the image will be converted to the Format_ARGB32_Premultiplied
- format if the function succeeds.
+ If \a alphaChannel is an 8 bit alpha image, the alpha values are
+ used directly. Otherwise, \a alphaChannel is converted to 8 bit
+ grayscale and the intensity of the pixel values is used.
- Use one of the composition modes in QPainter::CompositionMode instead.
+ If the image already has an alpha channel, the existing alpha channel
+ is multiplied with the new one. If the image doesn't have an alpha
+ channel it will be converted to a format that does.
- \warning This function is expensive.
+ The operation is similar to painting \a alphaChannel as an alpha image
+ over this image using \c QPainter::CompositionMode_DestinationIn.
- \sa alphaChannel(), {QImage#Image Transformations}{Image
- Transformations}, {QImage#Image Formats}{Image Formats}
+ \sa hasAlphaChannel(), alphaChannel(),
+ {QImage#Image Transformations}{Image Transformations},
+ {QImage#Image Formats}{Image Formats}
*/
void QImage::setAlphaChannel(const QImage &alphaChannel)
{
- if (!d)
+ if (!d || alphaChannel.isNull())
return;
- int w = d->width;
- int h = d->height;
-
- if (w != alphaChannel.d->width || h != alphaChannel.d->height) {
- qWarning("QImage::setAlphaChannel: "
- "Alpha channel must have same dimensions as the target image");
- return;
- }
-
if (d->paintEngine && d->paintEngine->isActive()) {
qWarning("QImage::setAlphaChannel: "
"Unable to set alpha channel while image is being painted on");
return;
}
- if (d->format == QImage::Format_ARGB32_Premultiplied)
+ const Format alphaFormat = qt_alphaVersionForPainting(d->format);
+ if (d->format == alphaFormat)
detach();
else
- *this = convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ convertTo(alphaFormat);
if (isNull())
return;
- // Slight optimization since alphachannels are returned as 8-bit grays.
- if (alphaChannel.format() == QImage::Format_Alpha8 ||( alphaChannel.d->depth == 8 && alphaChannel.isGrayscale())) {
- const uchar *src_data = alphaChannel.d->data;
- uchar *dest_data = d->data;
- for (int y=0; y<h; ++y) {
- const uchar *src = src_data;
- QRgb *dest = (QRgb *)dest_data;
- for (int x=0; x<w; ++x) {
- int alpha = *src;
- int destAlpha = qt_div_255(alpha * 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 += alphaChannel.d->bytes_per_line;
- dest_data += d->bytes_per_line;
- }
+ QImage sourceImage;
+ if (alphaChannel.format() == QImage::Format_Alpha8 || (alphaChannel.d->depth == 8 && alphaChannel.isGrayscale()))
+ sourceImage = alphaChannel;
+ else
+ sourceImage = alphaChannel.convertToFormat(QImage::Format_Grayscale8);
+ if (!sourceImage.reinterpretAsFormat(QImage::Format_Alpha8))
+ return;
- } else {
- const QImage sourceImage = alphaChannel.convertToFormat(QImage::Format_RGB32);
- if (sourceImage.isNull())
- return;
- const uchar *src_data = sourceImage.d->data;
- uchar *dest_data = d->data;
- 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 * 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.d->bytes_per_line;
- dest_data += d->bytes_per_line;
- }
- }
+ QPainter painter(this);
+ if (sourceImage.size() != size())
+ painter.setRenderHint(QPainter::SmoothPixmapTransform);
+ painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
+ painter.drawImage(rect(), sourceImage);
}
+#if QT_DEPRECATED_SINCE(5, 15)
/*!
\obsolete
@@ -4592,6 +4554,7 @@ QImage QImage::alphaChannel() const
return image;
}
+#endif
/*!
Returns \c true if the image has a format that respects the alpha
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index 7544ccca05..115071c16e 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -266,7 +266,9 @@ public:
bool hasAlphaChannel() const;
void setAlphaChannel(const QImage &alphaChannel);
- QImage alphaChannel() const;
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED QImage alphaChannel() const;
+#endif
QImage createAlphaMask(Qt::ImageConversionFlags flags = Qt::AutoColor) const;
#ifndef QT_NO_IMAGE_HEURISTIC_MASK
QImage createHeuristicMask(bool clipTight = true) const;
diff --git a/src/plugins/imageformats/ico/qicohandler.cpp b/src/plugins/imageformats/ico/qicohandler.cpp
index 6515748bf5..eb50f52bd6 100644
--- a/src/plugins/imageformats/ico/qicohandler.cpp
+++ b/src/plugins/imageformats/ico/qicohandler.cpp
@@ -535,8 +535,6 @@ QImage ICOReader::iconAt(int index)
if (!mask.isNull()) {
img = image;
img.setAlphaChannel(mask);
- // (Luckily, it seems that setAlphaChannel() does not ruin the alpha values
- // of partially transparent pixels in those icons that have that)
}
}
}