W3C home > Mailing lists > Public > public-css-archive@w3.org > April 2019

Re: [csswg-drafts] [filter-effects] Clarify the feComposite's arithmetic mode (#3831)

From: Evgeniy Reizner via GitHub <sysbot+gh@w3.org>
Date: Mon, 22 Apr 2019 20:42:35 +0000
To: public-css-archive@w3.org
Message-ID: <issue_comment.created-485545385-1555965754-sysbot+gh@w3.org>
I was able to reproduce the expected result using premultiplied colors:

```cpp
#include <QImage>
#include <QPainter>

static const int ImgWidth = 500;
static const int ImgHeight = 500;

static const double K1 = 0.1;
static const double K2 = 0.2;
static const double K3 = 0.3;
static const double K4 = 0.4;

static int calc(int c1, int c2)
{
    const double i1 = c1 / 255.0;
    const double i2 = c2 / 255.0;
    const double result = K1*i1*i2 + K2*i1 + K3*i2 + K4;

    return (int)(qBound(0.0, result, 1.0) * 255.0);
}

static QColor premultiply(const QColor c)
{
    const auto a = c.alpha() / 255.0;

    return QColor(c.red() * a + 0.5,
                  c.green() * a + 0.5,
                  c.blue() * a + 0.5,
                  c.alpha());
}

static QColor unmultiply(const QColor c)
{
    const auto a = c.alpha() / 255.0;

    return QColor(c.red() / a + 0.5,
                  c.green() / a + 0.5,
                  c.blue() / a + 0.5,
                  c.alpha());
}

int main()
{
    QImage img1(ImgWidth, ImgHeight, QImage::Format_ARGB32); // not premultiplied
    img1.fill(Qt::transparent);

    QImage img2(ImgWidth, ImgHeight, QImage::Format_ARGB32);
    img2.fill(Qt::transparent);

    QImage img3(ImgWidth, ImgHeight, QImage::Format_ARGB32);
    img3.fill(Qt::transparent);

    {
        QPainter p(&img1);
        p.fillRect(100, 100, 300, 300, QColor(0, 0, 255)); // blue
    }

    {
        QPainter p(&img2);
        p.setOpacity(0.5);
        p.fillRect(0, 0, 500, 500, QColor(0, 128, 0)); // green
    }

    for (int x = 0; x < ImgWidth; ++x) {
        for (int y = 0; y < ImgHeight; ++y) {
            const auto p1 = premultiply(img1.pixelColor(x, y));
            const auto p2 = premultiply(img2.pixelColor(x, y));

            const auto r = calc(p1.red(),   p2.red());
            const auto g = calc(p1.green(), p2.green());
            const auto b = calc(p1.blue(),  p2.blue());
            const auto a = calc(p1.alpha(), p2.alpha());

            img3.setPixelColor(x, y, unmultiply(QColor(r, g, b, a)));
        }
    }

    img3.save("test.png");

    return 0;
}
```

Does premultiplied colors are required? It isn't mentioned in the docs. And why exactly this multiplication method? It's the same one as in `cairo`, but Qt uses a completely different one.

-- 
GitHub Notification of comment by RazrFalcon
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/3831#issuecomment-485545385 using your GitHub account
Received on Monday, 22 April 2019 20:42:37 UTC

This archive was generated by hypermail 2.4.0 : Tuesday, 19 October 2021 01:31:07 UTC