GDI+的颜色矩阵由一个5*5的float型数组构成,用来对每一个像素的颜色(R,G,B,A)做线性变换,每个像素颜色与矩阵相乘。把一幅彩色图转成灰度图的算法是,假设像素点颜色为(r,g,b),转换成灰度图三个颜色分量是一样的,称作灰阶,灰阶的计算是 r*0.299+g*0.587+b*0.114。我们可以逐个像素转换,也可以使用颜色矩阵。所以彩色图转灰度图的颜色矩阵为
ColorMatrix matrix =
{0.299, 0.299, 0.299, 0, 0,
0.587, 0.587, 0.587, 0, 0,
0.114, 0.114, 0.114, 0, 0,
0, 0, 0, 1, 0,
0, 0, 0, 0, 0}
这样转换后,灰度图的灰阶分布在0~255之间。如果想把一幅彩色图渲染成双色图,定义一个深颜色darker,一个浅颜色lighter,那么灰度图只是一个darker是黑色而lighter是白色的特例。本来分布在0~255的灰阶,这样应该分别分布在(lighter.r~darker.r),(lighter.g~darker.g),(lighter.b~darker.b)。
编写代码如下,使用白色和紫色。
void CDuotoneDlg::OnButton1()
{
Bitmap img(L"c:\\test1.jpg");
Graphics graphix(this->GetDC()->m_hDC);
Color darker(0);
Color lighter(8414370);
const float gray_r = 0.299f;
const float gray_g = 0.587f;
const float gray_b = 0.114f;
float offset_r = (float)darker.GetR() / 255;
float offset_g = (float)darker.GetG() / 255;
float offset_b = (float)darker.GetB() / 255;
float r = (float)(lighter.GetR() - darker.GetR()) / 255;
float g = (float)(lighter.GetG() - darker.GetG()) / 255;
float b = (float)(lighter.GetB() - darker.GetB()) / 255;
ImageAttributes imgatt;
ColorMatrix matrix =
{
gray_r*r, gray_r*g, gray_r*b, 0, 0,
gray_g*r, gray_g*g, gray_g*b, 0, 0,
gray_b*r, gray_b*g, gray_b*b, 0, 0,
0, 0, 0, 1, 0,
offset_r, offset_g, offset_b, 0, 1
};
imgatt.SetColorMatrix(&matrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap);
int iWidth = img.GetWidth();
int iHeight = img.GetHeight();
graphix.DrawImage(
&img,
Rect(0, 0, iWidth, iHeight),
0.0f,
0.0f,
iWidth,
iHeight,
UnitPixel,
&imgatt);
graphix.ReleaseHDC(this->GetDC()->m_hDC);
}
渲染图片测试
posted on 2008-01-05 14:01
小四 阅读(640)
评论(0) 编辑 收藏 引用 所属分类:
图形图像与计算几何