Нарисуйте фигуру в GDI +, которая перекрывает непрозрачные пиксели с прозрачностью - PullRequest
3 голосов
/ 25 февраля 2010

У меня есть растровое изображение маски (bmpMask), которое я рисую на целевом растровом изображении (bmpDest). Оба растровых изображения имеют альфа-каналы, но уже заполнены непрозрачным контентом.

Я хочу создать прозрачные области, используя методы GDI + Draw ... на bmpMask, чтобы bmpDest просвечивал, когда я рисую над ним bmpMask.

Конечно, gMask.DrawLine(Pens.Transparent, 0, y, wMax, y) не вызывает никаких изменений в bmpMask, потому что GDI + работает как задумано и ничего не рисует, когда прозрачен. Даже с полупрозрачными цветами обновляются только значения r, g, b пикселей bmpMask.

Но я хочу запустить метод draw, который изменит альфа-канал bmpMask, чтобы он был прозрачным при рисовании на bmpDest. Я знаю, что могу сделать это с помощью SetPixel или более быстрых небезопасных или альтернатив Маршалла, но это приведет к гораздо более сложному решению. Спасибо.

Ответы [ 2 ]

6 голосов
/ 21 декабря 2012

Найден ответ через 3 года!

Я никогда не пытался найти решение Дэна, поэтому я не хочу от него отказываться, но это именно то, что я хочу:

    ' (setting composting mode is the key to getting the transparent
    ' line to actually result in setting the pixels to transparent-
    ' instead of just not drawing anything 'because it's transparent dummy' - 
    ' because it turns off the 'math' that is done to cause transparent
    ' image drawing to occur and just verbatim copies the bits).
    g1.CompositingMode = Drawing2D.CompositingMode.SourceCopy
    g1.DrawLine(Pens.Transparent, 0, y, wMax, y)
    g1.CompositingMode = Drawing2D.CompositingMode.SourceOver

CompostingMode это ключ! Я наконец-то снова попытался исправить эту проблему в моей программе, и поиск в Google обнаружил этот элемент, который не имеет ничего общего с тем, что я искал (эй, Google может прочитать ваши мысли).

Является ли Graphics.DrawImage слишком медленным для больших изображений?

Замечательно! Теперь 10 баксов говорят, что никто в мире не читает этого. 755

1 голос
/ 26 февраля 2010

Насколько мне известно, единственный способ изменить альфа-канал, как вы говорите, использовать SetPixel или (конечно, намного лучше) указатели. В зависимости от того, что вы пытаетесь сделать, вы можете обойтись с творческим использованием ColorMatrix. Это позволит вам изменить операцию DrawImage таким образом, чтобы вы могли поменять значение R / G / B / A при его рисовании. Попробуйте это, чтобы получить представление:

        using ( var bmp = new Bitmap( 100, 100 ) )
        using ( var g = Graphics.FromImage( bmp ) )
        using ( var ia = new ImageAttributes() )
        {
            float R = 1;
            float G = 0;
            float B = 0;
            ia.SetColorMatrix( new ColorMatrix( new float[][] {
                new float[] {1, 0, 0, R, 0},
                new float[] {0, 1, 0, G, 0},
                new float[] {0, 0, 1, B, 0},
                new float[] {0, 0, 0, 0, 0},
                new float[] {0, 0, 0, 0, 1}} ) );
            g.Clear( Color.White );
            g.FillEllipse( Brushes.Blue, 10, 10, 30, 30 );
            g.FillEllipse( Brushes.Red, 60, 10, 30, 30 );
            g.FillEllipse( Brushes.Green, 10, 60, 30, 30 );
            g.FillEllipse( Brushes.Black, 60, 60, 30, 30 );
            e.Graphics.DrawImage(
                bmp,
                new Rectangle( 0, 0, 100, 100 ),
                0, 0, 100, 100,
                GraphicsUnit.Pixel,
                ia );
        }

Попробуйте установить R / G / B на 1 соответственно и посмотрите, как это изменит то, какие цвета получаются сплошными / прозрачными. Но, если вы хотите напрямую изменить альфа-канал растрового изображения, вот как это сделать: Мягкие изображения в GDI +.

...