Графични специални ефекти в SDL - Евгений Бронников

3. Изсветляване и потъмняване

Тези ефекти ви позволяват да промените яркостта на дадено изображение: да го направите по-тъмно или по-светло. Както вече знаете, всеки пиксел от RGB изображение съдържа стойностите на цветовите компоненти: червено, зелено и синьо. Колкото по-малка е тази стойност, толкова по-тъмен е показаният цвят и обратното, колкото по-голяма е стойността, толкова по-светъл е цветът. Използвайки това знание, можем да променим стойността на всеки компонент с еднаква стойност, за да направим целия пиксел по-светъл или по-тъмен. Важно е да използвате една и съща сума за промяна на стойността на всеки компонент, тъй като цветът на един пиксел се формира от трите компонента и промяната на който и да е от тях ще доведе до загуба на оригиналния цвят.

И така, за да реализираме тези ефекти, трябва да увеличим или намалим стойността на всеки цветен компонент на пиксела с една и съща сума. Емпирично бяха избрани методите на трансформация за изсветляване и потъмняване на изображението, за което ще ви разкажа.

За да потъмним пиксела, отрязваме двата най-значими бита в стойността на цветния компонент. Например, ако компонентът има стойност 0xFF (или 11111111 в двоичен код), тогава отрязването на двата най-значими бита от еднобайтова стойност изглежда така:

За да разберем по-добре това действие, нека го запишем в двоична форма чрез действия:

На практика се оказа, че отрязването на двата най-значими бита от стойността на всеки цветен компонент ще има значително влияние върху оригиналния цвят на пиксела - засенчването ще бъде доста силно. Затова нека добавим трето действие - просто умножете получената стойност по 3. Крайната формула за преобразуване на всеки компонент е следната:

Където променливата Ch е всеки цветен компонент на пиксел (R, G, B).

Когато осветяваме пиксел, ниетрябва да увеличи стойностите на своите цветови компоненти, съгласно следната формула, също избрана емпирично:

За стойност от един байт всичко е доста просто. Сложността възниква при пикселите с дълбочина на цвета 15 и 16 бита (555 и 565). За да изглежда ефектът ни еднакъв за всички режими, беше избран коефициентът за 15 и 16 битови режими, като се вземе предвид фактът, че всеки компонент има 5 или 6 бита. Можете да използвате [RGB]полетата за загуба, описани по-рано, но това ще отнеме някои ресурси за възстановяване и пакетиране на цветовите компоненти. Можете да видите изпълнението на ефектите за 15 и 16-битови изображения в кода, приложен към статията.

Остава да разгледаме пример за изпълнение:

Можете сами да промените кода, за да можете да регулирате степента на изсветляване и потъмняване. Можете да намерите прилагането на ефекти за 15, 16, 24 и 32-битови изображения в източниците, приложени към статията.

4. Наситеност на цвета

poynton/Poynton-color.html. По този начин за всеки RGB цвят можете да изчислите стойността на яркост, използвана за преобразуване в скала на сивото (изображение в скала на сивото вместо стойност на цвят във всеки пиксел съдържа неговата стойност на яркост). За изчисления на яркостта можете да използвате тегловните коефициенти за всеки компонент:

В някои случаи, за да се изчисли стойността на яркостта на цвета, се използва средноаритметичната стойност на стойностите на компонентите:

Получената стойност е близка до реалната, но казват, че човешкото око практически не улавя тази грешка.

Сега нека разгледаме втория въпрос - как правилно да изчислим стойността на цвета (или по-скоро неговите компоненти - RGB), в зависимост от коефициента на насищане-регулатор. Можеш да използвашспециална функция mix , която има следния алгоритъм:

Тази функция връща стойност между X и Y, в зависимост от параметъра A, който в нашия случай е контролът на насищането. Аргументът X в нашия случай ще бъде стойността на яркостта (сивата скала), а аргументът Y ще бъде цветът на пиксела на оригиналното цветно изображение. По този начин копчето A задава съотношението на цветовия компонент: единица - цвят, нула - скала на сивото.

Сега можем да преминем към разглеждане на алгоритъма на нашата функция, която връща нова SDL повърхност с модифицирана наситеност на цвета. За всеки пиксел от изображението стойността на яркостта се изчислява с помощта на един от горните методи. След това на всеки компонент на пиксела се присвоява стойността, върната от функцията за смесване, в зависимост от фактора на насищане. Това всъщност е всичко, което трябва да се направи. Достатъчно просто, нали? Нека разгледаме прилагането на този ефект за 16-битовия режим.

Удобно е да се извлекат стойностите на цветовите компоненти на пиксел с помощта на функцията SDL_GetRGB, точно както изчисляването на стойността на пиксела от дадените стойности на цветовите компоненти с помощта на функцията SDL_MapRGB. Можете да получите и запишете тези стойности ръчно, както се прави при прилагането на този ефект за режими 24 и 32 бита на пиксел (вижте изходния код на приложението).

5. Разтваряне

Следващият ефект, представен на вашето внимание, ви позволява да разтворите (прелеете) едно изображение в друго. Изглежда, сякаш полупрозрачно изображение е насложено върху основното изображение, но всичко се прави програмно. Алгоритъмът на този ефект е много подобен на този, обсъден по-горе. Като параметри на функцията, която реализира този алгоритъм, ще предадем две изображения - основно и допълнително, разположено върху основното. Заза да контролираме дълбочината на смесване, ще използваме определен факторен параметър, който е обратно пропорционален на алфа стойността за цялата равнина на допълнителното изображение - колкото по-малка е стойността, толкова по-голяма е „непрозрачността“.

И така, нашата функция създава и връща ново изображение, което е "смес" от две оригинални изображения, смесени в дадена пропорция. За ново изображение трябва да изчислите всеки пиксел, като използвате формулата, спомената по-горе:

Ще използваме пиксел на изображението номер 2 (горния слой) като X променлива, а долния слой като Y променлива. Очевидно едно от ограниченията на тази реализация е, че изходните изображения трябва да имат идентични размери и формати. Помислете за пример за RGB повърхности с дълбочина на цвета от 16 бита на пиксел. Този код записва промени в повърхността1, предадена в параметрите:

Изпълнението на ефекта е доста подобно на предишното (Раздел 4), с изключение на това, че се използва пиксел от второто изображение вместо изчислената стойност на сивото. Можете да намерите кода на ефекта за изображения с дълбочина 24 и 32 бита на пиксел в приложението.