1.2 Графические фильтры: изменение яркости и контрастности изображения

Что прочитать перед этим материалом

1.1 Графические фильтры: «негатив» и «сепия»

В этом уроке мы научимся изменять яркость и контрастность изображения.

Изменение яркости изображения

Яркость - это световая характеристика тел, отношение силы света, излучаемого поверхностью, к площади ее проекции на плоскости, перпендикулярной оси наблюдения. Если сказать проще, это количество белого цвета на изображении. Чем выше яркость, тем светлее оно становится.

Вот формула, по которой мы будем изменять яркость:

Код:

Pixel[X, Y] = Pixel[X, Y] + Brightness; 
//где Pixel[X, Y] – это цвет пикселя с координатами X, Y, а Brightness – это значение яркости.

Значения яркости находятся в диапазоне от 0 до 255. Для того чтобы яркость можно было уменьшать и увеличивать, значения яркости берут в диапазоне от -255 до 255, затем по формуле вычисляют цвет и приводят к диапазону от 0 до 255.

Чтобы цвет был в диапазоне от 0 до 255, мы будем использовать функцию ToByte().

Создайте класс Brightness и добавьте в него функцию ToByte().

Код:

private static byte ToByte(int Val)
{
    if (Val > 255) Val = 255;
    else if (Val < 0) Val = 0;
    return (byte)Val;
}

Теперь нужно добавить функцию ProcessImage:

Код:

public static unsafe Bitmap ProcessImage(Filter Main,int Value)
{
    for (int I = 0; I < Main.AllPixelsBytes; I += Main.BytesPerPixel)
    {
        *(Main.Unsafe_IMG_Scan0 + I + 0) = ToByte(*(Main.Unsafe_IMG_Scan0 + I + 0) + Value);//B
        *(Main.Unsafe_IMG_Scan0 + I + 1) = ToByte(*(Main.Unsafe_IMG_Scan0 + I + 1) + Value);//G   
        *(Main.Unsafe_IMG_Scan0 + I + 2) = ToByte(*(Main.Unsafe_IMG_Scan0 + I + 2) + Value);//R
    }
    Main.UnLock();
    return Main.Picture;
}

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

Использование в приложениях: яркость

Код:

Bitmap Test1 = Brightness.ProcessImage(new Filter(TestImage),85); //TestImage - это ваше изображение
изображение до изменения яркости
Рисунок 1. Изображение до изменения яркости.
изображение после изменения яркости (+85)
Рисунок 2. Изображение после изменения яркости (+85).

Изменение контрастности изображения

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

Реализация контрастности немного сложнее. Чтобы контрастность можно было увеличивать и уменьшать, её значения берут от -100 до 100, а потом уже значение приводят к диапазону от 0 до 255.

Формула ее вычисления выглядит следующим образом:

Код:

Contrast = (100.0 + Value) / 255.0; //Вычисляем общее значение
Contrast = Contrast * Contrast;
//Вычисляем контрастность для заданного пикселя
Pixel= RGB_Channels / 255.0;
Pixel = Pixel - 0.5;
Pixel = Pixel * Contrast;
Pixel = Pixel + 0.5;
Pixel = Pixel * 255;

if(Pixel > 255) Pixel = 255;
else if(Pixel < 0) Pixel = 0;

RGB_Channels здесь – это каналы RGB (красный, зелёный, синий).

Создайте класс Contrast и добавьте в него функцию ProcessImage :

Код:

public static unsafe Bitmap ProcessImage(Filter Main,int Value)
{
    int RedVal, GreenVal, BlueVal;
   
    double Pixel;
    double Contrast = (100.0 + Value) / 100.0; //Вычисляем общее значение контраста

    Contrast = Contrast * Contrast;

    for (int I = 0; I < Main.AllPixelsBytes; I += Main.BytesPerPixel)
    {
        BlueVal = *(Main.Unsafe_IMG_Scan0 + (I + 0)); //B
        GreenVal = *(Main.Unsafe_IMG_Scan0 + (I + 1)); //G 
        RedVal = *(Main.Unsafe_IMG_Scan0 + (I + 2)); //R

        Pixel = RedVal / 255.0;
        Pixel = Pixel - 0.5;
        Pixel = Pixel * Contrast;
        Pixel = Pixel + 0.5;
        Pixel = Pixel * 255;
        if (Pixel < 0) Pixel = 0;
        if (Pixel > 255) Pixel = 255;
        *(Main.Unsafe_IMG_Scan0 + (I + 2)) = Convert.ToByte(Pixel);

        Pixel = GreenVal / 255.0;
        Pixel = Pixel - 0.5;
        Pixel = Pixel * Contrast;
        Pixel = Pixel + 0.5;
        Pixel = Pixel * 255;
        if (Pixel < 0) Pixel = 0;
        if (Pixel > 255) Pixel = 255;
        *(Main.Unsafe_IMG_Scan0 + (I + 1)) = Convert.ToByte(Pixel);

        Pixel = BlueVal / 255.0;
        Pixel = Pixel - 0.5;
        Pixel = Pixel * Contrast;
        Pixel = Pixel + 0.5;
        Pixel = Pixel * 255;
        if (Pixel < 0) Pixel = 0;
        if (Pixel > 255) Pixel = 255;
        *(Main.Unsafe_IMG_Scan0 + (I + 0)) = Convert.ToByte(Pixel);
    }
    Main.UnLock();
    return Main.Picture;
}

Готово!

Использование в приложениях: контрастность

Код:

Bitmap Test1 = Contrast.ProcessImage(new Filter(TestImage),35); //TestImage - это ваше изображение
изображение до изменения контрастности (+35)
Рисунок 3. Изображение до изменения контрастности.
изображение после изменения контрастности
Рисунок 4. Изображение после изменения контрастности (+35).