Подтвердить что ты не робот

Как управлять изображениями на уровне пикселей в С#

Как управлять изображениями на уровне пикселей в С#?

Мне нужно иметь возможность считывать/изменять каждый из RGB-значений растрового изображения отдельно.

Будет оценен образец кода.

4b9b3361

Ответ 1

Если вам нужна скорость, LockBits. См. здесь хорошее руководство по игре Боба Пауэлла. Если вы просто хотите отредактировать несколько, то GetPixel/SetPixel должен делать то, что вы хотите.

Ответ 2

Пример кода (я использую это для простой функции слияния и сравнения. Он принимает два изображения и создает третье изображение в оттенках серого, показывающее различия между двумя изображениями в качестве уровня тона оттенка серого. Чем темнее, тем больше разница.):

    public static Bitmap Diff(Bitmap src1, Bitmap src2, int x1, int y1, int x2, int y2, int width, int height)
{
    Bitmap diffBM = new Bitmap(width, height, PixelFormat.Format24bppRgb);

    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            //Get Both Colours at the pixel point
            Color col1 = src1.GetPixel(x1 + x, y1 + y);
            Color col2 = src2.GetPixel(x2 + x, y2 + y);

            // Get the difference RGB
            int r = 0, g = 0, b = 0;
            r = Math.Abs(col1.R - col2.R);
            g = Math.Abs(col1.G - col2.G);
            b = Math.Abs(col1.B - col2.B);

            // Invert the difference average
            int dif = 255 - ((r+g+b) / 3);

            // Create new grayscale RGB colour
            Color newcol = Color.FromArgb(dif, dif, dif);

            diffBM.SetPixel(x, y, newcol);

        }
    }

    return diffBM;
}

Марк пост отмечает LockBits и использует это для изменения изображения непосредственно в памяти. Я бы предложил посмотреть на это, а не на то, что я опубликовал, если производительность является проблемой. Спасибо Marc!

Ответ 3

System.Drawing.Bitmap имеет общедоступный метод GetPixel (int x, int y), который возвращает структуру System.Drawing.Color. В этой структуре есть байт-элементы R, G, B и A, которые вы можете изменить напрямую, а затем снова вызовите SetPixel (цвет) на вашем растровом изображении.
К сожалению, это будет относительно медленным, но это проще всего сделать на С#. Если вы много работаете с отдельными пикселями и обнаруживаете, что производительность отсутствует, вам нужно что-то быстрее, вы можете использовать LockBits... Это намного сложнее, поскольку вам нужно понять структуру битов для этой глубины и типа цвета, и работать с растровым шагом, а что нет... так что если вы сочтете это необходимым, убедитесь, что вы нашли хороший учебник! В Интернете есть несколько веб-сайтов, Googling "С# LockBits" доставит вам полдюжины, которые стоит прочитать.

Ответ 4

Если производительность критическая, другой альтернативой LockBits управляет DirectX.

Более подробную информацию см. в предыдущем вопросе о переполнении стека рендеринг графики на С#.

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

Вы также получаете более высокую производительность при рендеринге по DirectX, по сравнению с обычным классом Bitmap и PictureBox.