Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 需要更快的方法来替换基于另一种颜色的图像中的颜色_Vb.net_Image Processing_Colors_Image Manipulation - Fatal编程技术网

Vb.net 需要更快的方法来替换基于另一种颜色的图像中的颜色

Vb.net 需要更快的方法来替换基于另一种颜色的图像中的颜色,vb.net,image-processing,colors,image-manipulation,Vb.net,Image Processing,Colors,Image Manipulation,我正在寻找一种基于另一种颜色替换图像中颜色的更快方法。例如,我有一个图像,大部分是黑色的,带有灰色阴影,我想基于红色对其进行重新着色。现在我将它传递到这个函数中,黑色作为我的基色,红色作为我的新颜色。然后我逐像素确定它的RGB,并重新计算到新的红色阴影。所以纯黑色变成纯红色,灰色变成浅红色等等 有没有更快的方法?是否可能使用单独的图像处理库?我查看了ImageMagick,但找不到我想要的确切功能 这是我当前的函数。它可以工作,但速度很慢 Public Function doRecolorIma

我正在寻找一种基于另一种颜色替换图像中颜色的更快方法。例如,我有一个图像,大部分是黑色的,带有灰色阴影,我想基于红色对其进行重新着色。现在我将它传递到这个函数中,黑色作为我的基色,红色作为我的新颜色。然后我逐像素确定它的RGB,并重新计算到新的红色阴影。所以纯黑色变成纯红色,灰色变成浅红色等等

有没有更快的方法?是否可能使用单独的图像处理库?我查看了ImageMagick,但找不到我想要的确切功能

这是我当前的函数。它可以工作,但速度很慢

Public Function doRecolorImage(ByRef inBMP As Bitmap, ByVal baseColor As Color, ByVal newColor As Color) As Bitmap
        Dim newimg As New Bitmap(inBMP.Width, inBMP.Height)

            Using gIcons As Graphics = Graphics.FromImage(newimg)
                For x = 0 To inBMP.Width - 1
                    For y = 0 To inBMP.Height - 1
                        Dim ltrans As Byte = inBMP.GetPixel(x, y).A
                        Dim lR As Byte = inBMP.GetPixel(x, y).R
                        Dim lG As Byte = inBMP.GetPixel(x, y).G
                        Dim lB As Byte = inBMP.GetPixel(x, y).B

                        Dim newpixR As Integer = CInt(newColor.R) + (CInt(lR) - CInt(baseColor.R))

                        Dim newpixG As Integer = CInt(newColor.G) + (CInt(lG) - CInt(baseColor.G))

                        Dim newpixB As Integer = CInt(newColor.B) + (CInt(lB) - CInt(baseColor.B))

                        newimg.SetPixel(x, y, System.Drawing.Color.FromArgb(ltrans, newpixR, newpixG, newpixB))
                    Next
                Next
            End Using

        Return newimg

    End Function
在这里,我尝试使用ColorMatrix,但它不起作用,不知道为什么…也许我对ColorMatrix工作原理的理解是错误的

Public Function doNewRecolorImage(ByRef inBMP As Bitmap, ByVal baseColor As Color, ByVal newColor As Color) As Bitmap
        Dim newimg As New Bitmap(inBMP.Width, inBMP.Height)


            Dim iaImageProps As New ImageAttributes 

            Dim cmNewColors As ColorMatrix 

            cmNewColors = New ColorMatrix(New Single()() _
                {New Single() {newColor.R / baseColor.R, 0, 0, 0, 0}, _
                 New Single() {0, newColor.G / baseColor.G, 0, 0, 0}, _
                 New Single() {0, 0, newColor.B / baseColor.B, 0, 0}, _
                 New Single() {0, 0, 0, 1, 0}, _
                 New Single() {0, 0, 0, 0, 1}})

            iaImageProps.SetColorMatrix(cmNewColors) 

            Using g As Graphics = Graphics.FromImage(newimg)
                g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality
                g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
                g.DrawImage(inBMP, New Rectangle(0, 0, inBMP.Width, inBMP.Height), 0, 0, inBMP.Width, inBMP.Height, GraphicsUnit.Pixel, iaImageProps)
            End Using


        Return newimg

    End Function
更新1: 下面是我根据Ryan的回答更新的函数。它会运行,但不会返回预期的重新存储图像。图像是一种纯色…基色。因此,我将传递基础颜色和新颜色,并得到结果。但是,结果应该是新颜色(深蓝色),因为图像是纯色,所以应该是精确的颜色交换

更新2(解决方案): 以下是解决方案:基于Ryan下面的答案

Private Function calcColorSwap(_base As Byte, _new As Byte) As Single
        Return (CInt(_new) - CInt(_base)) / 255.0!
End Function

Public Function doNewRecolorImage(inBMP As Bitmap, baseColor As Color, newColor As Color) As Bitmap
    Dim newimg As New Bitmap(inBMP.Width, inBMP.Height)
    Dim transformation As 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() {calcColorSwap(baseColor.R, newColor.R), calcColorSwap(baseColor.G, newColor.G), calcColorSwap(baseColor.B, newColor.B), 0, 1}
      })

    Dim imageAttributes As New ImageAttributes()
    imageAttributes.SetColorMatrix(transformation)


    Using g As Graphics = Graphics.FromImage(newimg)
        g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality
        g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
        g.DrawImage(inBMP, New Rectangle(0, 0, inBMP.Width, inBMP.Height), 0, 0, inBMP.Width, inBMP.Height, GraphicsUnit.Pixel, imageAttributes)
    End Using

Return newimg

End Function

与原始矩阵等效的矩阵–向R、G和B添加固定值–如下所示:

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() {(CInt(newColor.R) - CInt(baseColor.R)) / 255!, (CInt(newColor.G) - CInt(baseColor.G)) / 255!, (CInt(newColor.B) - CInt(baseColor.B)) / 255!, 0, 1}
}
总体而言:

Public Function doRecolorImage(image As Image, baseColor As Color, newColor As Color) As Bitmap
    Dim transformation As 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() {(CInt(newColor.R) - CInt(baseColor.R)) / 255!, (CInt(newColor.G) - CInt(baseColor.G)) / 255!, (CInt(newColor.B) - CInt(baseColor.B)) / 255!, 0, 1}
    })

    Dim imageAttributes As New ImageAttributes()
    imageAttributes.SetColorMatrix(transformation)

    Dim result As New Bitmap(image.Width, image.Height)

    Using g As Graphics = Graphics.FromImage(result)
        g.DrawImage(image, New Rectangle(0, 0, image.Width, image.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imageAttributes)
    End Using

    Return result
End Function

(不要无缘无故地使用
ByRef

在ImageMagick中,您可以这样做

convert gray.png \( -clone 0 -fill red -colorize 100 \) \( -clone 0 -negate \) -compose colorize -composite red.png
我在这里回答了一个类似的问题(没有否定)

ImageMagick中另一种更简单、更符合您需要的方法是:

convert gray.png +level-colors red,white red.png

请参见

我测试了您的代码,请参见上面我更新的代码。当
baseColor
值大于
newColor
值时,它抛出了一个错误(无法转换为字节),因此我添加了一个函数来切换它们…但不确定这是否是正确的逻辑。而且,当图像是纯色时,它也没有达到我所期望的效果。@ChaseRocker:If不应该有
;始终按相同的顺序减去
CInt(newColor.R-baseColor.R)/255。它会抛出一个错误。例如,当new=87和base=255时,它抛出一个溢出异常:更新到我的上一条注释:我将其更改为此,现在它可以工作了:
(CInt(_new)-CInt(_base))/255.0。谢谢你在这方面的帮助。@ChaseRocker:啊,对不起,我显然很累,忘了中间的事了!
convert gray.png +level-colors red,white red.png