Hier eine schnell gebastelte Primitivlösung.
Es ist eine Bilddatei und ein zu ersetzende Farbe
sowie die Breite der RGB-Umgebung anzugeben.
Die Abfolge der R-G-B-Teile im Speicher kann bei
manchen Systemen vertauscht sein (+2 und +0 in der
Schleife ggf. austauschen).
''' <summary>Eine Farbe (incl. RGB-Umgebung) ersetzen</summary>
''' <param name="Bilddatei_in">zu lesende Bilddatei</param>
''' <param name="OldColor">zu ersetzende Farbe</param>
''' <param name="ReplaceWidth">halbe Breite des Ersetzbereichs</param>
''' <param name="NewColor">Neue Farbe</param>
''' <param name="Bilddatei_out">zu schreibende Bilddatei</param>
Public Shared Sub Farbe_Ersetzen(ByVal Bilddatei_in As String, _
ByVal OldColor As Drawing.Color, _
ByVal ReplaceWidth As Byte, _
ByVal NewColor As Drawing.Color, _
ByVal Bilddatei_out As String)
Dim x, y As Integer ' Loop
Dim Byte_Index As Integer ' Index im 1D-Array
If ReplaceWidth < 1 Then ReplaceWidth = 1
'Farbumgebung ermitteln (RGB-Bereich)
Dim red_min, green_min, blue_min As Byte
Dim red_max, green_max, blue_max As Byte
ByteSector(OldColor.R, ReplaceWidth, red_min, red_max)
ByteSector(OldColor.G, ReplaceWidth, green_min, green_max)
ByteSector(OldColor.B, ReplaceWidth, blue_min, blue_max)
' Bitmap aus Datei laden
Dim bmp_in As New Drawing.Bitmap(Bilddatei_in)
' Rectangle für die Größe des gesamten geladenen Bildes erstellen
Dim bmp_rect As New Drawing.Rectangle(0, 0, bmp_in.Width, bmp_in.Height)
' Eine Arbeits-Bitmap (24-Bit pro Pixel) in der erforderlichen Größe
' erstellen
Dim bmp As New System.Drawing.Bitmap(bmp_in.Width, bmp_in.Height, _
Drawing.Imaging.PixelFormat.Format24bppRgb)
' Ein Zeichnenobjekt für 'bmp' erstellen
Dim mg As Drawing.Graphics = Drawing.Graphics.FromImage(bmp)
mg.DrawImage(bmp_in, bmp_rect)
mg.Dispose() : bmp_in.Dispose()
' Bilddaten (ggf. Ausschnitt) im Speicher sperren
Dim bmp_data As Drawing.Imaging.BitmapData = _
bmp.LockBits(bmp_rect, Drawing.Imaging.ImageLockMode.ReadWrite, _
bmp.PixelFormat)
' Array für Bitmapdaten in geeigneter Größe erstellen
Dim bmp_bytes As Integer = bmp_data.Stride * bmp.Height
Dim bmp_array(0 To bmp_bytes - 1) As Byte
' Die Bitmapdaten in das Array kopieren
Runtime.InteropServices.Marshal.Copy _
(bmp_data.Scan0, bmp_array, 0, bmp_bytes)
' Die Bilddaten bearbeiten
For y = 1 To bmp.Height
For x = 1 To bmp.Width
Byte_Index = (y - 1) * bmp_data.Stride + (x - 1) * 3
If bmp_array(Byte_Index + 2) >= red_min AndAlso _
bmp_array(Byte_Index + 2) <= red_max Then
If bmp_array(Byte_Index + 1) >= green_min AndAlso _
bmp_array(Byte_Index + 1) <= green_max Then
If bmp_array(Byte_Index + 0) >= blue_min AndAlso _
bmp_array(Byte_Index + 0) <= blue_max Then
bmp_array(Byte_Index + 2) = NewColor.R
bmp_array(Byte_Index + 1) = NewColor.G
bmp_array(Byte_Index + 0) = NewColor.B
End If
End If
End If
Next x
Next y
' Die modifizierten Arraydaten in die Bitmap zurück-kopieren
Runtime.InteropServices.Marshal.Copy _
(bmp_array, 0, bmp_data.Scan0, bmp_bytes)
With bmp
.UnlockBits(bmp_data)
.Save(Bilddatei_out, Bildformat(Bilddatei_out))
.Dispose()
End With
End Sub |