From 97594601ca84ae11f30bb35e6cbc7e3f70e0624d Mon Sep 17 00:00:00 2001 From: Ariya Hidayat Date: Mon, 14 Sep 2009 12:24:33 +0200 Subject: Add strength factor to the colorize filter. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To allow fading between the original and the colorized version of the pixmaps, a new strength factor is introduced, 0.0 means the filter has no effect at all, 1.0 means full colorization. Still missing is the non-raster implementation. Autotest: included Reviewed-by: Bjørn Erik Nilsen --- src/gui/image/qpixmapfilter.cpp | 51 +++++++++++++++++++++++++- src/gui/image/qpixmapfilter_p.h | 3 ++ tests/auto/qpixmapfilter/tst_qpixmapfilter.cpp | 41 +++++++++++++++++++++ 3 files changed, 94 insertions(+), 1 deletion(-) diff --git a/src/gui/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp index 15704ba..4fa2e6c 100644 --- a/src/gui/image/qpixmapfilter.cpp +++ b/src/gui/image/qpixmapfilter.cpp @@ -759,6 +759,10 @@ class QPixmapColorizeFilterPrivate : public QPixmapFilterPrivate Q_DECLARE_PUBLIC(QPixmapColorizeFilter) public: QColor color; + qreal strength; + quint32 opaque : 1; + quint32 alphaBlend : 1; + quint32 padding : 30; }; /*! @@ -771,7 +775,11 @@ public: QPixmapColorizeFilter::QPixmapColorizeFilter(QObject *parent) : QPixmapFilter(*new QPixmapColorizeFilterPrivate, ColorizeFilter, parent) { - d_func()->color = QColor(0, 0, 192); + Q_D(QPixmapColorizeFilter); + d->color = QColor(0, 0, 192); + d->strength = qreal(1); + d->opaque = true; + d->alphaBlend = false; } /*! @@ -797,6 +805,31 @@ void QPixmapColorizeFilter::setColor(const QColor &color) } /*! + Gets the strength of the colorize filter, 1.0 means full colorized while + 0.0 equals to no filtering at all. + + \internal +*/ +qreal QPixmapColorizeFilter::strength() const +{ + Q_D(const QPixmapColorizeFilter); + return d->strength; +} + +/*! + Sets the strength of the colorize filter to \a strength. + + \internal +*/ +void QPixmapColorizeFilter::setStrength(qreal strength) +{ + Q_D(QPixmapColorizeFilter); + d->strength = qBound(qreal(0), strength, qreal(1)); + d->opaque = !qFuzzyIsNull(d->strength); + d->alphaBlend = !qFuzzyIsNull(d->strength - 1); +} + +/*! \internal */ void QPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const @@ -807,6 +840,7 @@ void QPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const Q QPixmapColorizeFilter *colorizeFilter = static_cast(filter); if (colorizeFilter) { colorizeFilter->setColor(d->color); + colorizeFilter->setStrength(d->strength); colorizeFilter->draw(painter, dest, src, srcRect); delete colorizeFilter; return; @@ -814,6 +848,11 @@ void QPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const Q // falling back to raster implementation + if (!d->opaque) { + painter->drawPixmap(dest, src, srcRect); + return; + } + QImage srcImage; QImage destImage; @@ -836,6 +875,16 @@ void QPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const Q destPainter.fillRect(srcImage.rect(), d->color); destPainter.end(); + if (d->alphaBlend) { + // alpha blending srcImage and destImage + QImage buffer = srcImage; + QPainter bufPainter(&buffer); + bufPainter.setOpacity(d->strength); + bufPainter.drawImage(0, 0, destImage); + bufPainter.end(); + destImage = buffer; + } + if (srcImage.hasAlphaChannel()) destImage.setAlphaChannel(srcImage.alphaChannel()); diff --git a/src/gui/image/qpixmapfilter_p.h b/src/gui/image/qpixmapfilter_p.h index 4cbf7a3..2565110 100644 --- a/src/gui/image/qpixmapfilter_p.h +++ b/src/gui/image/qpixmapfilter_p.h @@ -155,6 +155,9 @@ public: void setColor(const QColor& color); QColor color() const; + void setStrength(qreal strength); + qreal strength() const; + void draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect = QRectF()) const; }; diff --git a/tests/auto/qpixmapfilter/tst_qpixmapfilter.cpp b/tests/auto/qpixmapfilter/tst_qpixmapfilter.cpp index 83bd537..5a9bad7 100644 --- a/tests/auto/qpixmapfilter/tst_qpixmapfilter.cpp +++ b/tests/auto/qpixmapfilter/tst_qpixmapfilter.cpp @@ -63,8 +63,10 @@ public slots: private slots: void colorizeSetColor(); + void colorizeSetStrength(); void colorizeProcess(); void colorizeDraw(); + void colorizeDrawStrength(); void colorizeDrawSubRect(); void colorizeProcessSubRect(); void convolutionBoundingRectFor(); @@ -127,6 +129,16 @@ void tst_QPixmapFilter::colorizeSetColor() QCOMPARE(filter.color(), QColor(50, 100, 200)); } +void tst_QPixmapFilter::colorizeSetStrength() +{ + QPixmapColorizeFilter filter; + QCOMPARE(filter.strength(), qreal(1)); + filter.setStrength(0.5); + QCOMPARE(filter.strength(), qreal(0.5)); + filter.setStrength(0.0); + QCOMPARE(filter.strength(), qreal(0.0)); +} + void tst_QPixmapFilter::colorizeProcess() { QPixmapColorizeFilter filter; @@ -180,6 +192,35 @@ void tst_QPixmapFilter::colorizeDraw() } } +void tst_QPixmapFilter::colorizeDrawStrength() +{ + QPixmapColorizeFilter filter; + filter.setColor(Qt::blue); + filter.setStrength(0.3); + + QImage source(256, 128, QImage::Format_ARGB32); + source.fill(qRgb(255, 0, 0)); + QPixmap pixmap = QPixmap::fromImage(source); + + QImage result(pixmap.size(), QImage::Format_ARGB32_Premultiplied); + QPainter painter(&result); + painter.setCompositionMode(QPainter::CompositionMode_Source); + filter.draw(&painter, QPointF(0, 0), pixmap); + painter.end(); + + QImage resultImg = result; + for(int y = 0; y < resultImg.height(); y++) + { + for(int x = 0; x < resultImg.width(); x++) + { + QRgb pixel = resultImg.pixel(x,y); + QCOMPARE(qRed(pixel), 206); + QCOMPARE(qGreen(pixel), 26); + QCOMPARE(qBlue(pixel), 75); + } + } +} + void tst_QPixmapFilter::colorizeDrawSubRect() { QPixmapColorizeFilter filter; -- cgit v0.12