在Android NDK中的颜色叠加
Color overlay in android NDK
我想实现色相/颜色/饱和色覆盖层。我看到了宏:
#define ColorBlend_Saturation(T,A,B) ColorBlend_Hls(T,A,B,HueA,LuminationA,SaturationB)
我试图在带有颜色#332244
和#557711
的Adobe Photoshop中复制它,以获得结果颜色-#431076
。但是,应用这些宏后,我得到了颜色-#320C59
结果。
问题1 :如何重现用于色相,饱和和颜色的Photoshop算法?
问题2 :如何调整Alpha通道?例如,在我的颜色上,光学== 50,这应该在Photoshop中 - #3B195D
问题1:
Photoshop的色相,饱和度,颜色和光度混合模式基于具有尺寸的颜色空间,该尺寸为HSL和HSV称为Hue,Chroma和Luma。请注意,此空间与HSL和HSV都不同,并且在这三个空间之间仅共享色调尺寸。有关详细信息,请参见该文章。
色相混合模式保留了底层的LUMA和色度,同时采用顶层的色相。
饱和混合模式保留了底层的LUMA和色调,同时采用顶层的色度。
颜色混合模式保留了底层的LUMA,同时采用顶层的色相和色度。
来自http://en.wikipedia.org/wiki/blend_modes
经过3个多小时的实验,我成功地将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(r.R*255) << endl;
cout << int(r.G*255) << endl;
cout << int(r.B*255) << endl;
}
原始HSV&lt; -> RGB转换器代码在这里:http://wiki.beyondunreal.com/hsv-rgb_conversion
问题2。
饱和实际上很容易,在饱和混合后使用RGB颜色空间中的正常alpha混合。
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引擎SDK。
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 如何在内核C++中使用1920x1080x16M图形或类似的16M颜色?(VGA)
- 如何在24位SDL_Surface上设置像素的颜色
- 如何从SDL_Surface获取特定像素的颜色
- 列表视图更改选择颜色
- GtkTreeView 交替行颜色
- dx11 渲染到纹理仅显示透明颜色
- 使用 OpenGL 4.5 更改所选顶点的颜色
- 为什么我的 LEGACY OPENGL 颜色反转了?
- 双击更改 mfc 中列表控件中的行的颜色
- 更改 QT 中按钮的颜色
- 当我使用CHAR_INFO结构时,控制台会无缘无故地改变颜色
- 列表视图项的替代颜色
- GLSL 将 uint 转换为浮点颜色
- std::带有颜色和标题的 clog 包装器无法正确打印整数
- Vec3b:r/g/b 颜色的最大值为 254,而不是 255
- 如何将矢量对象更改为不同的颜色?
- PPM 颜色显示错误
- 如何更改 QGraphicsItem 对象的颜色?
- 在Android NDK中的颜色叠加