Внимание!

Эта публикация перенесена в раздел уроков по адресу Графические фильтры на основе попиксельной обработки изображений (Часть 2).
К ней прикреплена новая отдельная ветка комментариев форума, которую вы можетет найти после текста публикации.
Обсуждение публикации рекуомендуется вести по новому адресу, который указан выше.

Графические фильтры на основе попиксельной обработки изображений (Часть 2)

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

Пара изображений для примера.

Оригинал


Контрастность + 35

[spoiler]

С первой частью урока можно ознакомиться по ссылке работа с фильтрами часть 1


Яркость
Вот формула, по которой мы будем изменять яркость:
/*http://esate.ru, Alexei16*/


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

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

/*http://esate.ru, Alexei16*/


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

Теперь нужно добавить функцию ProcessImage :
/*http://esate.ru, Alexei16*/


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;
}

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

Контрастность

Реализация контрастности немного сложнее.Чтобы контрастность можно было увеличивать и уменьшать,её значеня берут от -100 до 100,а потом уже значение приводят к диапазону от 0 до 255. Вот формула для её вычисления:
/*http://esate.ru, Alexei16*/


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 :
/*http://esate.ru, Alexei16*/


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;
}

Готово!

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

• Яркость
/*http://esate.ru, Alexei16*/


Bitmap Test1 = Brightness.ProcessImage(new Filter(TestImage),85); //TestImage - это ваше изображение



Оригинал


Яркость + 85

• Контрастность
/*http://esate.ru, Alexei16*/


Bitmap Test1 = Contrast.ProcessImage(new Filter(TestImage),35); //TestImage - это ваше изображение



Оригинал


Контрастность + 35
0       1304        26.12.2010        3

Внимание!

Эта публикация перенесена в раздел уроков по адресу Графические фильтры на основе попиксельной обработки изображений (Часть 2).
К ней прикреплена новая отдельная ветка комментариев форума, которую вы можетет найти после текста публикации.
Обсуждение публикации рекуомендуется вести по новому адресу, который указан выше.

0  
26.12.2010 00:00:00
Спасибо за урок!
Перенес в «Новые уроки OpenGL и мультимедиа»
0  
26.12.2010 00:00:00
Nice! Так держать
0  
08.01.2011 00:00:00
Супер, мне очень пригодилось.
^