Intereting Posts
Тестовая активность onCreate Exception Android получает вид вида Предотвращение слишком большого растрового изображения для добавления в текстуру android Отображение большего количества строк в Logcat Как работает математика AppBarLayout.ScrollingViewBehavior? Ящик навигации не закрывается Как отличить, если данный Контекстный объект является Контекстом Деятельности или Сервиса? Переключение фрагментов внутри вкладки Как воспроизводить видео в android из папки с ресурсами или в необработанной папке? Повторное использование атрибутов xml для Android Custom enum Транслитерация с хинди на английский язык на Android без использования API Google Как проверить имя сертификата и псевдоним в файлах хранилища ключей? Эффекты изображения для Android? Как изменить идентификатор группы файла на корневом устройстве Android? Android TextureView vs Производительность видеопроигрывателя

Наложение цвета в андроид NDK

Я хочу реализовать наложения цвета Hue / color / saturation. Я видел макросы:

#define ColorBlend_Saturation(T,A,B) ColorBlend_Hls(T,A,B,HueA,LuminationA,SaturationB) 

Я пытаюсь воспроизвести его в Adobe Photoshop с цветами #332244 и #557711 чтобы получить цвет результата – #431076 . Однако после применения этих макросов я получаю цвет – #320C59 .

Вопрос 1 : как я могу воспроизвести алгоритмы photoshop для оттенка, насыщенности и цвета?

Вопрос 2 : как настроить альфа-канал? Например, по моим цветам и оптически == 50, это должно быть в фотошопе – # 3b195d

Solutions Collecting From Web of "Наложение цвета в андроид NDK"

Вопрос 1:

Цветовые режимы, оттенки, насыщенность, цвет и светимость Photoshop основаны на цветовом пространстве с размерами, которые статья HSL и HSV вызывает оттенок, цветность и яркость. Обратите внимание, что это пространство отличается от HSL и HSV, и только размер оттенка разделяется между тремя; Подробности см. В этой статье.

Режим смешивания оттенков сохраняет яркость и цветность нижнего слоя, принимая оттенок верхнего слоя.

Режим наложения насыщенности сохраняет яркость и оттенок нижнего слоя, принимая цветность верхнего слоя.

Режим «Цветная смесь» сохраняет яркость нижнего слоя, принимая оттенок и цветность верхнего слоя.

С http://en.wikipedia.org/wiki/Blend_modes

После более чем трех часов экспериментов я добился обновления HSV -> RGB-конвертера до рабочего насыщающего блендера. Другие режимы смешивания должны быть одинаковыми.

Вот код:

 #include <cmath> #include <iostream> using namespace std; struct HSVColor { float H,S,V; }; struct RGBColor { float R,G,B; RGBColor() = default; RGBColor(int r,int g, int b): R(r/255.0), G(g/255.0), B(b/255.0) { } }; HSVColor RGBToHSV(const RGBColor& RGB) { float Max; float Min; float Chroma; HSVColor HSV; Min = min(min(RGB.R, RGB.G), RGB.B); Max = max(max(RGB.R, RGB.G), RGB.B); Chroma = Max - Min; //If Chroma is 0, then S is 0 by definition, and H is undefined but 0 by convention. if(Chroma != 0) { if(RGB.R == Max) { HSV.H = (RGB.G - RGB.B) / Chroma; if(HSV.H < 0.0) { HSV.H += 6.0; } } else if(RGB.G == Max) { HSV.H = ((RGB.B - RGB.R) / Chroma) + 2.0; } else //RGB.B == Max { HSV.H = ((RGB.R - RGB.G) / Chroma) + 4.0; } HSV.H *= 60.0; HSV.S = Chroma / Max; } HSV.V = Max; return HSV; } RGBColor Saturate(const HSVColor& HSV,const HSVColor& overlay) { float os = overlay.S; float ov = overlay.V; float Min; float Chroma; float Hdash; float X; RGBColor RGB{0,0,0}; Chroma = os * ov; // Orginal was HSV.S * HSV.V Hdash = HSV.H / 60.0; X = Chroma * (1.0 - abs(fmod(Hdash , 2.0) - 1.0)); if(Hdash < 1.0) { RGB.R = Chroma; RGB.G = X; } else if(Hdash < 2.0) { RGB.R = X; RGB.G = Chroma; } else if(Hdash < 3.0) { RGB.G = Chroma; RGB.B = X; } else if(Hdash < 4.0) { RGB.G= X; RGB.B = Chroma; } else if(Hdash < 5.0) { RGB.R = X; RGB.B = Chroma; } else if(Hdash <= 6.0) { RGB.R = Chroma; RGB.B = X; } Min = ov - Chroma; // Orginal was HSV.V - Chroma RGB.R += Min; RGB.G += Min; RGB.B += Min; return RGB; } int main(){ RGBColor base{51, 34, 68}; RGBColor overly{85, 119, 17}; RGBColor r = Saturate(RGBToHSV(base),RGBToHSV(overly)); cout << int(rR*255) << endl; cout << int(rG*255) << endl; cout << int(rB*255) << endl; } 

Оригинальный HSV <-> код конвертера RGB здесь: http://wiki.beyondunreal.com/HSV-RGB_Conversion

вопрос 2.

С насыщением это на самом деле легко, После насыщения смешивания используйте нормальное альфа-смешивание в цветовом пространстве rgb.

 RGBColor base; RGBColor overly; RGBColor saturated = Saturate(base,overly); RGBColor result = AlphaBlend(base,saturated,overly.alpha); 

Примечание: это может не работать с другими режимами смешивания.

Вот уравнения для разных режимов смешивания Photoshop:

  inline float Blend_Normal( float Base, float Overlay ) { return Base; } inline float Blend_Lighten( float Base, float Overlay ) { return ( Overlay > Base ) ? Overlay : Base; } inline float Blend_Darken( float Base, float Overlay ) { return ( Overlay > Base ) ? Base : Overlay; } inline float Blend_Multiply( float Base, float Overlay ) { return Base * Overlay; } inline float Blend_Average( float Base, float Overlay ) { return ( Base + Overlay ) / 2.0f; } inline float Blend_Add( float Base, float Overlay ) { return LMin( Base + Overlay, 1.0f ); } inline float Blend_Subtract( float Base, float Overlay ) { return LMax( Base + Overlay - 1.0f, 0.0f ); } inline float Blend_Difference( float Base, float Overlay ) { return fabs( Base - Overlay ); } inline float Blend_Negation( float Base, float Overlay ) { return 1.0f - fabs( 1.0f - Base - Overlay ); } inline float Blend_Screen( float Base, float Overlay ) { return 1.0f - ( 1.0f - Base ) * ( 1.0f - Overlay ); } inline float Blend_Exclusion( float Base, float Overlay ) { return Base + Overlay - 2 * Base * Overlay; } inline float Blend_Overlay( float Base, float Overlay ) { return ( Overlay < 0.5f ) ? ( 2.0f * Base * Overlay ) : ( 2.0f * Base - 1.0f ) * ( 1.0f - Overlay ); } inline float Blend_SoftLight( float Base, float Overlay ) { return ( Overlay < 0.5f ) ? ( Base + 0.5f ) * Overlay : ( Base - 0.5f ) * ( 1.0f - Overlay ); } inline float Blend_HardLight( float Base, float Overlay ) { return Blend_Overlay( Overlay, Base ); } inline float Blend_ColorDodge( float Base, float Overlay ) { return ( Overlay > 1.0f - Math::EPSILON ) ? Overlay : LMin( 1.0f, Base / ( 1.0f - Overlay ) ); } inline float Blend_ColorBurn( float Base, float Overlay ) { return ( Overlay < Math::EPSILON ) ? Overlay : LMax( 0.0f, 1.0f - ( 1.0f - Base ) / Overlay ); } inline float Blend_LinearDodge( float Base, float Overlay ) { return Blend_Add( Base, Overlay ); } inline float Blend_LinearBurn( float Base, float Overlay ) { return Blend_Subtract( Base, Overlay ); } inline float Blend_LinearLight( float Base, float Overlay ) { return ( Overlay < 0.5f ) ? Blend_LinearBurn( Base, 2 * Overlay ) : Blend_LinearDodge( Base, ( 2 * ( Overlay - 0.5f ) ) ); } inline float Blend_VividLight( float Base, float Overlay ) { return ( Overlay < 0.5f ) ? Blend_ColorBurn( Base, 2 * Overlay ) : Blend_ColorDodge( Base, ( 2 * ( Overlay - 0.5f ) ) ); } inline float Blend_PinLight( float Base, float Overlay ) { return ( Overlay < 0.5f ) ? Blend_Darken( Base, 2 * Overlay ) : Blend_Lighten( Base, ( 2 * ( Overlay - 0.5f ) ) ); } inline float Blend_HardMix( float Base, float Overlay ) { return ( Blend_VividLight( Base, Overlay ) < 0.5f ) ? 0.0f : 1.0f; } inline float Blend_Reflect( float Base, float Overlay ) { return ( Overlay > 1.0f - Math::EPSILON ) ? Overlay : LMin( 1.0f, Base * Base / ( 1.0f - Overlay ) ); } inline float Blend_Glow( float Base, float Overlay ) { return Blend_Reflect( Overlay, Base ); } inline float Blend_Phoenix( float Base, float Overlay ) { return LMin( Base, Overlay ) - LMax( Base, Overlay ) + 1.0f; } 

От Linderdaum Engine SDK .