Графични специални ефекти в 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 бита на пиксел в приложението.