GDI +: установить для всех пикселей заданный цвет с сохранением существующего альфа-значения.

Как лучше всего установить компоненты RGB каждого пикселя в System.Drawing.Bitmap на один сплошной цвет? Если возможно, я бы не хотел вручную перебирать каждый пиксель, чтобы сделать это.

Примечание: я хочу сохранить тот же альфа-компонент из исходного растрового изображения. Я хочу изменить только значения RGB.

Я искал возможность использовать ColorMatrix или ColorMap, но не смог найти способа установить для всех пикселей определенный заданный цвет с помощью любого из подходов.


person Charles    schedule 24.03.2010    source источник


Ответы (3)


Да, используйте ColorMatrix. Это должно выглядеть так:

  0  0  0  0  0
  0  0  0  0  0
  0  0  0  0  0 
  0  0  0  1  0 
  R  G  B  0  1

Где R, G и B - масштабированные значения цвета замещающего цвета (разделить на 255.0f)

person Hans Passant    schedule 24.03.2010
comment
Это не устанавливает цвет каждого пикселя на определенный цвет, не так ли? Я почти уверен, что это увеличило бы каждый цветовой канал на R, G и B. Я хочу, чтобы все изображение было сплошным цветом, сохраняя только прозрачность / альфа каждого пикселя. - person Charles; 24.03.2010
comment
Нули на диагонали дают черный цвет, нижние числа складываются. - person Hans Passant; 24.03.2010
comment
Ага. Я не обдумывал все это до конца. Бьюсь об заклад, это должно работать отлично. Я проверю и скоро вернусь к вам. - person Charles; 24.03.2010
comment
Превосходно! Большое спасибо, nobugz. - person Charles; 25.03.2010
comment
Спасибо, Ганс. Я пропустил деление на 255, и это сводило меня с ума! Я собрал загружаемое пошаговое руководство и пример, если кому-то интересно: blog.benpowell.co.uk/2011/01/ - person Rebecca; 13.01.2011
comment
Я пробовал это. Создал ColorMatrix, назначил его ImageAttributes и использовал при рисовании с DrawImage. Отлично работает на Win7 и более поздних версиях, однако XP и Vista вызывают проблемы, есть ли у вас идеи, как это решить? - person ST3; 21.08.2014

Я знаю, что на это уже дан ответ, но на основе ответа Ханса Пассанта результирующий код выглядит примерно так:

public class Recolor
{
    public static Bitmap Tint(string filePath, Color c)
    {
        // load from file
        Image original = Image.FromFile(filePath);
        original = new Bitmap(original);

        //get a graphics object from the new image
        Graphics g = Graphics.FromImage(original);

        //create the ColorMatrix
        ColorMatrix colorMatrix = new ColorMatrix(
            new float[][]{
                    new float[] {0, 0, 0, 0, 0},
                    new float[] {0, 0, 0, 0, 0},
                    new float[] {0, 0, 0, 0, 0},
                    new float[] {0, 0, 0, 1, 0},
                    new float[] {c.R / 255.0f,
                                 c.G / 255.0f,
                                 c.B / 255.0f,
                                 0, 1}
                });

        //create some image attributes
        ImageAttributes attributes = new ImageAttributes();

        //set the color matrix attribute
        attributes.SetColorMatrix(colorMatrix);

        //draw the original image on the new image
        //using the color matrix
        g.DrawImage(original, 
            new Rectangle(0, 0, original.Width, original.Height),
            0, 0, original.Width, original.Height,
            GraphicsUnit.Pixel, attributes);

        //dispose the Graphics object
        g.Dispose();

        //return a bitmap
        return (Bitmap)original;
    }
}

Загрузите рабочую демонстрацию здесь: http://benpowell.org/change-the-color-of-a-transparent-png-image-icon-on-the-fly-using-asp-net-mvc/ < / а>

person Rebecca    schedule 11.01.2011

Лучшим (по крайней мере с точки зрения производительности) вариантом является использование Bitmap.LockBits и прокрутите пиксельные данные в строке развертки, задав значения RGB.

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

person Reed Copsey    schedule 24.03.2010
comment
+1. Спасибо, Рид, я, наверное, воспользуюсь этим для других вещей, которыми занимаюсь. - person Charles; 25.03.2010