WriteableBitmapEx проблема цвета альфа-смеси - PullRequest
0 голосов
/ 16 апреля 2019

Я пытаюсь использовать WriteableBitmap с методами расширения WriteableBitmapEx.Пример кода ниже вместе с двумя скриншотами.Первый снимок экрана - это то, что генерирует мой код, а второй - то, что я ожидаю (нарисовано от Paint.Net).

Я неправильно использую WriteableBitmapEx, неправильно понимая, как он работает, или это ошибка?

Это на .Net 4.6.1 и WriteableBitmapEx 1.6.2.

    public MainWindow()
    {
        InitializeComponent();

        _bitmap = BitmapFactory.New(1000, 1000);

        _bitmap.FillRectangle(0,0,1000,1000, ColorToInt(Colors.White), true);

        _bitmap.FillRectangle(100, 100, 500, 500, ColorToInt(_color), true);
        _bitmap.FillRectangle(150, 150, 550, 550, ColorToInt(_color), true);
        _bitmap.FillRectangle(200, 200, 600, 600, ColorToInt(_color), true);
        _bitmap.FillRectangle(250, 250, 650, 650, ColorToInt(_color), true);
        _bitmap.FillRectangle(300, 300, 700, 700, ColorToInt(_color), true);
        _bitmap.FillRectangle(350, 350, 750, 750, ColorToInt(_color), true);
        _bitmap.FillRectangle(400, 400, 800, 800, ColorToInt(_color), true);

        Image1.Source = _bitmap;
    }

    private readonly Color _color = Color.FromArgb(25, 0, 0, 255);
    private WriteableBitmap _bitmap;

    private int ColorToInt(Color c)
    {
        return c.A << 24 | c.R << 16 | c.G << 8 | c.B;
    }

Image my code generates. Blue channel is gradually lost?

Paint.Net generating what I'd expect

1 Ответ

1 голос
/ 17 апреля 2019

WriteableBitmap использует предварительно умноженную альфу для внутреннего использования, поэтому при преобразовании цвета необходимо учитывать это и умножать свои цветовые каналы на альфа.

Вы можете просто использовать метод ConvertColor, которыйпоставляется с WBX или сверните свой собственный аналогичный этому:

    public static int ConvertColor(Color color)
    {
        var col = 0;

        if (color.A != 0)
        {
            var a = color.A + 1;
            col = (color.A << 24)
              | ((byte)((color.R * a) >> 8) << 16)
              | ((byte)((color.G * a) >> 8) << 8)
              | ((byte)((color.B * a) >> 8));
        }

        return col;
     }
...