65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.75/5 (47投票s)

2003 年 3 月 12 日

CPOL

3分钟阅读

viewsIcon

484698

downloadIcon

4

使用 GDI+ ColorMatrix 的初学者指南。

Color Image Grayscale Image Blue Image

引言

本文讨论了使用 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 轻松执行的更多常见操作。

© . All rights reserved.