我正在尋找一種更快速的方法,以基於另一種顏色替換圖像中的顏色。例如,我的圖像大多是黑色,灰色,我想根據紅色重新着色。現在我把它作爲我的基本顏色和紅色作爲我的新顏色傳遞給這個函數。然後,我逐像素地確定其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
在這裏,我嘗試使用嘉洛斯但它沒有工作,不知道爲什麼......也許我的嘉洛斯是如何工作的認識是錯誤的。
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:
下面是基於以下瑞安的回答我的更新功能。它運行,但它沒有返回預期的重新着色圖像。圖像是一種純色......基本顏色。所以我會傳遞基本顏色和新顏色並獲得結果。但是,結果應該是新顏色(深藍色),因爲圖像是純色,所以它應該是精確的顏色交換。
Private Function calcColorSwap(_base As Byte, _new As Byte) As Single
If _new > _base Then
Return (CInt(_new) - CInt(_base))/255.0!
Else
Return (CInt(_base) - CInt(_new))/255.0!
End If
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
更新2(液):
這裏的解決方案:基於以下瑞安的答案。
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
我測試了你的代碼,看到我上面更新的代碼。當'baseColor'值大於'newColor'值時,它拋出一個錯誤_(無法轉換爲Byte)_因此我添加了一個函數來切換它們......不知道這是否是正確的邏輯。另外,當圖像是純色時,它並不完全符合我的期望。 –
@ChaseRocker:不應該有'If';總是以相同的順序減去CInt(newColor.R - baseColor.R)/ 255!'。 – Ryan
它引發錯誤。例如,當new = 87和base = 255時,它會引發溢出異常:http://i.imgur.com/54V0e4H.jpg –