ColorMatrix 基础 -简单的图像颜色调整






4.75/5 (47投票s)
使用 GDI+ ColorMatrix 的初学者指南。
引言
本文讨论了使用 GDI+ 提供的新的 ColorMatrix
类对数字图像进行颜色操作。 ColorMatrix
是对 GDI 库的欢迎补充,尤其是在对数字成像应用的需求增加的情况下,因为越来越多的消费产品被推出。这个类,以及许多其他新的 GDI 类,为开发人员提供了更多的控制,并减少了对第三方应用程序(如 LEAD 工具等)的依赖。 本文假设读者对矩阵运算(乘法、加法等)、RGBA 颜色空间和 GDI+ 有一些基本的了解。
背景
ColorMatrix
操作在 RGBA 颜色空间(红、绿、蓝、alpha)中执行。一个 ColorMatrix
由一个 5x5 矩阵组成,颜色值被标准化为 1 以表示完全强度 (255 -> 1.0)。 您可能期望矩阵为 4x4 ( [R, G, B, A] ),如果我们只需要执行线性变换(乘法:缩放、旋转等),这将足够了。 但是,最常见的颜色操作之一,颜色调整,需要添加颜色值。 这是一个非线性操作,称为平移。 将第 5 个元素添加到颜色向量 ( [R, G, B, A, w] ) 将这两种操作(线性和非线性)合并为一个操作,称为仿射变换。 颜色向量的第 5 个元素只是一个虚拟元素,始终值为 1,它仅用于允许颜色向量的平移(加法)。
下面的示例将颜色向量 [255, 128, 102, 255] 缩放 0.5,然后将值 26 添加到 R、G 和 B 分量,保持 A 分量为完全强度。 记住,分量值是标准化的,完全强度 255 等于 1.0(值已四舍五入到最接近的十分位)。 还要注意颜色向量中第 5 个元素的添加,它在结果颜色向量中被简单地忽略。
这会将颜色 转换为
。
现在我们已经介绍了 ColorMatrix
的基本原理及其对颜色向量的操作,我们可以开始探索一些实际应用。
应用代码
将 ColorMatrix
应用于图像非常简单。 您必须首先将 ColorMatrix
对象与 ImageAttributes
对象关联。 然后您只需将 ImageAttributes
对象作为参数传递给 Graphics.DrawImage
方法。
颜色调整是对数字图像应用的一种更常见的颜色操作。 执行此操作的代码可能如下所示
Public Function translate(ByVal img As Image, ByVal red As Single, _
ByVal green As Single, ByVal blue As Single, _
Optional ByVal alpha As Single = 0) As Boolean
Dim sr, sg, sb, sa As Single
' noramlize the color components to 1
sr = red / 255
sg = green / 255
sb = blue / 255
sa = alpha / 255
' create the color matrix
dim New ColorMatrix(New Single()() _
{New Single() {1, 0, 0, 0, 0}, _
New Single() {0, 1, 0, 0, 0}, _
New Single() {0, 0, 1, 0, 0}, _
New Single() {0, 0, 0, 1, 0}, _
New Single() {sr, sg, sb, sa, 1}})
' apply the matrix to the image
Return draw_adjusted_image(img, cm)
End Function
Private Function draw_adjusted_image(ByVal img As Image, _
ByVal cm As ColorMatrix) As Boolean
Try
Dim bmp As New Bitmap(img) ' create a copy of the source image
Dim imgattr As New ImageAttributes()
Dim rc As New Rectangle(0, 0, img.Width, img.Height)
Dim g As Graphics = Graphics.FromImage(img)
' associate the ColorMatrix object with an ImageAttributes object
imgattr.SetColorMatrix(cm)
' draw the copy of the source image back over the original image,
'applying the ColorMatrix
g.DrawImage(bmp, rc, 0, 0, img.Width, img.Height, _
GraphicsUnit.Pixel, imgattr)
g.Dispose()
Return True
Catch
Return False
End Try
End Function
转换为灰度是另一种常见的转换。 灰度值是通过计算颜色的亮度来确定的,它是 R、G 和 B 颜色分量的加权平均值。 平均值根据人眼对每个颜色分量的敏感度进行加权。 这里使用的权重由 NTSC(北美电视标准委员会)给出,并且被广泛接受。
Public Function grayscale(ByVal img As Image) As Boolean
Dim cm As ColorMatrix = New ColorMatrix(New Single()() _
{New Single() {0.299, 0.299, 0.299, 0, 0}, _
New Single() {0.587, 0.587, 0.587, 0, 0}, _
New Single() {0.114, 0.114, 0.114, 0, 0}, _
New Single() {0, 0, 0, 1, 0}, _
New Single() {0, 0, 0, 0, 1}})
Return draw_adjusted_image(img, cm)
End Function
下面的代码创建一个数字负片
Public Function negative(ByVal img As Image) As Boolean
Dim cm As ColorMatrix = New ColorMatrix(New Single()() _
{New Single() {-1, 0, 0, 0, 0}, _
New Single() {0, -1, 0, 0, 0}, _
New Single() {0, 0, -1, 0, 0}, _
New Single() {0, 0, 0, 1, 0}, _
New Single() {0, 0, 0, 0, 1}})
Return draw_adjusted_image(img, cm)
End Function
颜色通道分离、alpha 透明度调整、图像色调调整(棕褐色等)只是可以用 ColorMatrix
轻松执行的更多常见操作。