Инвертировать изображение быстрее в C#

Я использую WinForms. У меня есть коробка с картинками в моей форме. Когда я открываю изображение в графическом окне, я могу инвертировать цвета назад и вперед по нажатию кнопки, но мой код очень медленный. Как я могу увеличить производительность.

   private void Button1_Click(object sender, System.EventArgs e) 
     {
        Bitmap pic = new Bitmap(PictureBox1.Image);
        for (int y = 0; (y 
                    <= (pic.Height - 1)); y++) {
            for (int x = 0; (x 
                        <= (pic.Width - 1)); x++) {
                Color inv = pic.GetPixel(x, y);
                inv = Color.FromArgb(255, (255 - inv.R), (255 - inv.G), (255 - inv.B));
                pic.SetPixel(x, y, inv);
                PictureBox1.Image = pic;
            }

        }

    }

4 ответа

Решение

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

Bitmap pic = new Bitmap(PictureBox1.Image);
for (int y = 0; (y <= (pic.Height - 1)); y++) {
    for (int x = 0; (x <= (pic.Width - 1)); x++) {
        Color inv = pic.GetPixel(x, y);
        inv = Color.FromArgb(255, (255 - inv.R), (255 - inv.G), (255 - inv.B));
        pic.SetPixel(x, y, inv);
    }
}
PictureBox1.Image = pic;

Улучшая предложение Д. Стэнли и избегая перегрузки памяти и обработки при преобразовании изображения в растровое изображение и последующем его повторном назначении, вы фактически можете напрямую получать и устанавливать пиксели в .Image PictureBox, просто заключая его и вызывая связанное растровое изображение. манипуляционные функции:

      private void Button1_Click(object sender, System.EventArgs e) 
 {
    for (int y = 0; (y 
                <= (PictureBox1.Image.Height - 1)); y++) {
        for (int x = 0; (x 
                    <= (PictureBox1.Image.Width - 1)); x++) {
            Color inv = ((Bitmap)PictureBox1.Image).GetPixel(x, y);
            inv = Color.FromArgb(255, (255 - inv.R), (255 - inv.G), (255 - inv.B));
            ((Bitmap)PictureBox1.Image).SetPixel(x, y, inv);

        }

    }
}

На случай, если кому-то понадобится аналогичный код на VB.NET.

Также обратите внимание на переменную inv.A вместо значения 255. Если ваш графический блок имеет прозрачность, вам это понадобится.

    Public Function InvertImageColors(ByVal p As Image) As Image
        Dim pic As New Bitmap(p)
        For y As Integer = 0 To pic.Height - 1
            For x As Integer = 0 To pic.Width - 1
                Dim inv As Color = pic.GetPixel(x, y)
                inv = Color.FromArgb(inv.A, 255 - inv.R, 255 - inv.G, 255 - inv.B)
                pic.SetPixel(x, y, inv)
            Next x
        Next y
        Return pic
    End Function

Применение:

    pic.image = InvertImageColors(pic.image)

Это работа для меня...

        private Image InvertingImage(Image source)
    {
        //create a blank bitmap the same size as original
        Bitmap newBitmap = new Bitmap(source.Width, source.Height);

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

        // create the negative color matrix
        ColorMatrix colorMatrix = new ColorMatrix(new float[][]
{
    new float[] {-1, 0, 0, 0, 0},
    new float[] {0, -1, 0, 0, 0},
    new float[] {0, 0, -1, 0, 0},
    new float[] {0, 0, 0, 1, 0},
    new float[] {1, 1, 1, 0, 1}
});

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

        attributes.SetColorMatrix(colorMatrix);

        g.DrawImage(source, new Rectangle(0, 0, source.Width, source.Height),
                    0, 0, source.Width, source.Height, GraphicsUnit.Pixel, attributes);

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

        return newBitmap;
    }
Другие вопросы по тегам