| |
VB.NET - Ein- und UmsteigerBild mit Transparente Farbe funktioniert nur mit der langsamen Methode | | | Autor: Volker Bunge | Datum: 16.02.13 11:19 |
| Hallo Zusammen,
mein Bildbearbeitungsprogramm funktioniert schon recht gut.
Ich möchte nun, einen vorher angeklickten Farbwert ersetzen durch color.transparent.
Mit einer For-to-Next Schleife funktioniert dies auch so, wie ich mir das vorstelle. Nachteil: Die Bearbeitung ist recht langsam.
Im Netz habe ich nun eine super schnelle Methode gefunden. Leider ersetzt diese irgendwie die Farbe nicht auf Transparent.
Benötigt werden 4 Textboxen für die ARGB Werte, Textbox für die Farbabweichung, Picturebox für das Bild. Checkbox für die Wahl der Methode und einen Button um das Ersetzen zu starten.
Meine Frage ist nun, warum klappt die langsame Methode und bei der schnellen Methode wird zwar die Farbe ersetzt, diese ist aber ehr ein grau Ton als transparent.
Die Farbabweichung stellt einen Wert dar, der den Abstand für die RGB-Farbwerte darstellt.
Bsp: Liegt R bei 150 und die Abweichung ist auf 5 eingestellt, so soll die Routine alle Werte von 145 bis 155 suchen und ersetzen. Wie gesagt, funktioniert bei der langsamen Methode für meine Bedürfnisse einwandfrei.
Für eine Lösung bei der schnelleren Methode wäre ist sehr dankbar.
Volker
P.S: Code siehe Antwort | |
Re: Bild mit Transparente Farbe funktioniert nur mit der langsamen Methode | | | Autor: Volker Bunge | Datum: 16.02.13 11:20 |
| Hier nun der Code
Private Sub BtnTransparenteFarbeEntfernen_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) Handles _
BtnTransparenteFarbeEntfernen.Click
If LangsamesTransperentVerfahren.Checked = false Then
GoTo BtnTransparenteFarbeEntfernen_Click_Langsam
End If
Cursor = Cursors.WaitCursor
Dim Diff As Integer = Farbabweichung.Text
Dim A As Integer = AktuelleFarbeA.Text
Dim R As Integer = AktuelleFarbeR.Text
Dim G As Integer = AktuelleFarbeG.Text
Dim B As Integer = AktuelleFarbeB.Text
Dim RN As Integer
Dim GN As Integer
Dim BN As Integer
Dim z As Integer
Dim myBitmap As New Bitmap(BildAnzeigeNeu.Image)
For z = Diff * -1 To Diff
RN = R + z
GN = G + z
BN = B + z
If RN < 0 Then
RN = 0
End If
If RN > 255 Then
RN = 255
End If
If GN < 0 Then
GN = 0
End If
If GN > 255 Then
GN = 255
End If
If BN < 0 Then
BN = 0
End If
If BN > 255 Then
BN = 255
End If
' MsgBox(z & " RN " & RN & " GN " & GN & " BN " & BN)
'PictureBox1.Image = ReplaceColor(Image.FromFile(Label1.Text),
' Color.FromArgb(255, RN, GN, BN), Color.Aquamarine)
'PictureBox1.Image = ReplaceColor(PictureBox1.Image, Color.FromArgb(
' 255, RN, GN, BN), Color.Aquamarine)
myBitmap = ReplaceColor(myBitmap, Color.FromArgb(A, RN, GN, BN), _
Color.FromArgb(0, 0, 0, 0))
Next
BildAnzeigeNeu.Image = myBitmap
Cursor = Cursors.Arrow
Exit Sub
BtnTransparenteFarbeEntfernen_Click_Langsam:
Dim BMP As Bitmap = BildAnzeigeNeu.Image
'Dim VAktuelleFarbeA As Integer
'Dim VAktuelleFarbeR As Integer
'Dim VAktuelleFarbeG As Integer
'Dim VAktuelleFarbeB As Integer
Dim AktuellA As Integer
Dim AktuellR As Integer
Dim AktuellG As Integer
Dim AktuellB As Integer
Cursor = Cursors.WaitCursor
' Color [A=255, R=31, G=28, B=22]
'AktuelleFarbeA = Mid(AktuelleFarbe.Text, InStr(1, AktuelleFarbe.Text,
' "A=") + 2, 3)
'AktuelleFarbeR = Mid(AktuelleFarbe.Text, InStr(1, AktuelleFarbe.Text,
' "R=") + 2, 3)
'AktuelleFarbeG = Mid(AktuelleFarbe.Text, InStr(1, AktuelleFarbe.Text,
' "G=") + 2, 3)
'AktuelleFarbeB = Val(Mid(AktuelleFarbe.Text, InStr(1,
' AktuelleFarbe.Text, "B=") + 2, 3))
'VAktuelleFarbeA = AktuelleFarbeA.Text
'VAktuelleFarbeR = AktuelleFarbeR.Text
'VAktuelleFarbeG = AktuelleFarbeG.Text
'VAktuelleFarbeB = AktuelleFarbeB.Text
' Wenn die gewählte Farbe schon Weiss ist, dann die Sub verlassen
If AktuelleFarbeA.Text + AktuelleFarbeR.Text + AktuelleFarbeG.Text + _
AktuelleFarbeB.Text = 0 Then
Cursor = Cursors.Arrow
Exit Sub
End If | |
Re: Bild mit Transparente Farbe funktioniert nur mit der langsamen Methode | | | Autor: Volker Bunge | Datum: 16.02.13 11:21 |
| ' MsgBox(BMP.Width & " " & BMP.Height)
For x As Integer = 0 To BMP.Width - 1 ' Val(Me.Breite.Text) - 1 ' Val( _
Me.XPos.Text) + 1 To Val(Me.Breite.Text) - 1
For y As Integer = 0 To BMP.Height - 1 ' Val(Me.Höhe.Text) - 1 'Val( _
Me.YPos.Text) + 1 To Val(Me.Höhe.Text) - 1
'MsgBox(BMP.GetPixel(x, y).ToString & " " &
' Me.AktuelleFarbe.Text)
BearbeiteteAktuelleFarbe.Text = BMP.GetPixel(x, y).ToString
AktuellA = Mid(BearbeiteteAktuelleFarbe.Text, InStr(1, _
BearbeiteteAktuelleFarbe.Text, "A=") + 2, 3)
AktuellR = Mid(BearbeiteteAktuelleFarbe.Text, InStr(1, _
BearbeiteteAktuelleFarbe.Text, "R=") + 2, 3)
AktuellG = Mid(BearbeiteteAktuelleFarbe.Text, InStr(1, _
BearbeiteteAktuelleFarbe.Text, "G=") + 2, 3)
AktuellB = Val(Mid(BearbeiteteAktuelleFarbe.Text, InStr(1, _
BearbeiteteAktuelleFarbe.Text, "B=") + 2, 3))
' If BMP.GetPixel(x, y).ToString = Me.AktuelleFarbe.Text Then
' 'Or BMP.GetPixel(x, y).ToString = "Color [A=255, R=252," & _
"G=255, B=255]" Or BMP.GetPixel(x, y).A = 0 Or BMP.GetPixel(x, _
y).R > 250 Or BMP.GetPixel(x, y).G > 250 Or BMP.GetPixel( _
x, y).B > 250 Then
' If AktuelleFarbeA=AktuellA and AktuelleFarbeR=AktuellR and
' AktuelleFarbeG=AktuellG and AktuelleFarbeB=AktuellB and
If Abweichnung_Farbwert(AktuellR, AktuelleFarbeR.Text, "R") = _
True And Abweichnung_Farbwert(AktuellG, AktuelleFarbeG.Text, _
"G") = True And Abweichnung_Farbwert(AktuellB, _
AktuelleFarbeB.Text, "B") = True Then
' If AktuelleFarbeR = AktuellR And AktuelleFarbeG =
' AktuellG And AktuelleFarbeB = AktuellB Then
BMP.SetPixel(x, y, Color.Transparent)
End If
Next
'MsgBox("")
Next
BildAnzeigeNeu.Image = BMP
BildAnzeigeNeu.Refresh()
Cursor = Cursors.Arrow
End Sub
Public Function ReplaceColor(ByVal oBitmap As Image, ByVal OldColor As _
Color, ByVal NewColor As Color) As Image
' ColorMap mit Zuweisung der zu konvertierenden
' Farben(erstellen)
Dim oMap(0) As ColorMap
oMap(0) = New ColorMap
With oMap(0)
.OldColor = OldColor
.NewColor = NewColor
End With
' ImageAttributes-Objekt mit Farbanpassung erstellen
Dim oAttr As New ImageAttributes
oAttr.SetRemapTable(oMap)
' Neues Image-Objektop erstellen
Dim imgWidth As Integer = oBitmap.Width
Dim imgHeight As Integer = oBitmap.Height
Dim oImage As Image = Image.FromHbitmap(New Bitmap(imgWidth, _
imgHeight).GetHbitmap)
Using g As Graphics = Graphics.FromImage(oImage)
g.DrawImage(oBitmap, New Rectangle(0, 0, imgWidth, imgHeight), 0, _
0, imgWidth, imgHeight, GraphicsUnit.Pixel, oAttr)
End Using
' neues Bild zurückgeben
Return oImage
End Function
Function Abweichnung_Farbwert(ByVal Farbwert1 As Integer, ByVal Farbwert2 As _
Integer, ByVal Farbe As String) As Boolean
Abweichnung_Farbwert = False
Dim DIff As Integer
DIff = System.Math.Abs(Farbwert1 - Farbwert2)
Select Case Farbe
Case "A"
If DIff <= My.Settings.FarbAbweichungA Then ' DIff >=
' My.Settings.AbweichungA * -1 And DIff <=
' My.Settings.AbweichungA Then
Abweichnung_Farbwert = True
End If
Case "R"
If DIff <= My.Settings.FarbAbweichungR Then 'DIff >=
' My.Settings.AbweichungR * -1 And DIff <=
' My.Settings.AbweichungR Then
Abweichnung_Farbwert = True
End If
Case "G"
If DIff <= My.Settings.FarbAbweichungG Then ' DIff >=
' My.Settings.AbweichungG * -1 And DIff <=
' My.Settings.AbweichungG Then
Abweichnung_Farbwert = True
End If
Case "B"
If DIff <= My.Settings.FarbAbweichungB Then 'DIff >=
' My.Settings.AbweichungB * -1 And DIff <=
' My.Settings.AbweichungB Then
Abweichnung_Farbwert = True
End If
End Select
End Function
Beitrag wurde zuletzt am 16.02.13 um 11:24:11 editiert. | |
Re: Bild mit Transparente Farbe funktioniert nur mit der langsamen Methode | | | Autor: Christoph1972 | Datum: 16.02.13 22:18 |
| Hi,
ich habe deinen Code jetzt nicht gelesen, hier ist jedoch eine Methode die sehr schnell & transparent macht:
private Bitmap SetTransparent(Bitmap vectorImage)
{
//ist bei mir immer der Hintergrund, musst du für dich anpassen!
Color c = vectorImage.GetPixel(10, 10);
vectorImage.MakeTransparent(c);
return vectorImage;
} Falls das auch deine "schnelle" Methode ist, hast du eventuell ein Problem mit deinem Hintergrund!?
Gruß
Christoph
| |
Re: Bild mit Transparente Farbe funktioniert nur mit der langsamen Methode | | | Autor: Volker Bunge | Datum: 17.02.13 16:46 |
| Hallo Christoph,
vielen Dank für Deine schnelle Antwort.
Wenn ich deinen Code kopiere, bekomme ich einige Fehler angezeigt. Daher gehe ich davon aus, dass es kein VB.NET - Code ist, oder doch?
Hast Du den Code auch als VB.NET-Code vorliegen?
Vielen Dank
Volker | |
Re: Bild mit Transparente Farbe funktioniert nur mit der langsamen Methode | | | Autor: Volker Bunge | Datum: 17.02.13 18:49 |
| Hallo Christoph,
vielen Dank für den Übersetzungslink.
Nun habe ich deinen Code mal ausprobiert. Soweit es die Geschwindigkeit betrifft ist er wirklich schnell.
Was ich aber festgestellt habe, ist folgendes:
Wenn ich meine Farbabweichung benutze, dann ist das Ergebnis mit Deiner Methode recht dürftig. Meine langsame Methode liefert mir mit nur 2-3 Durchläufen ein besseres Ergebnis.
Nicht das Du dies evtl. falsch verstehst. Die Geschwindigkeit ist echt super, nur halt das Ergebnis ist leider nicht so das ware.
Hier nun mal Code, den ich angepasst habe
Public Class Form3
Private Sub BildanzeigeNeu_MouseClick(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles BildanzeigeNeu.MouseClick
BildanzeigeNeu.Image = aSetTransparent(BildanzeigeNeu.Image)
End Sub
Private Sub BildanzeigeNeu_MouseMove(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles BildanzeigeNeu.MouseMove
Me.XMouse.Text = e.X
Me.YMouse.Text = e.Y
If Me.XMouse.Text > BildanzeigeNeu.Width Or Me.YMouse.Text > _
BildanzeigeNeu.Height Then Exit Sub
If IsNothing(BildanzeigeNeu.Image) Then Exit Sub
Dim myBitmap As New Bitmap(BildanzeigeNeu.Image)
On Error Resume Next
Dim pixelColor As Color = myBitmap.GetPixel(Val(Me.XMouse.Text), Val( _
Me.YMouse.Text))
AktuelleFarbeA.Text = pixelColor.A
AktuelleFarbeR.Text = pixelColor.R
AktuelleFarbeG.Text = pixelColor.G
AktuelleFarbeB.Text = pixelColor.B
Call BildanzeigeNeu.Refresh()
End Sub
Private Sub BildanzeigeNeu_Paint(ByVal sender As Object, ByVal e As _
System.Windows.Forms.PaintEventArgs) Handles BildanzeigeNeu.Paint
' Fadenkreuz zeichnen
Dim fk As Graphics = e.Graphics
Dim Ypoints As Point() = {New Point(0, Val(YMouse.Text)), New Point( _
Me.BildanzeigeNeu.Width, Val(Me.YMouse.Text))}
fk.DrawLines(Pens.Black, Ypoints)
Dim Xpoints As Point() = {New Point(Val(XMouse.Text), 0), New Point(Val( _
Me.XMouse.Text), Me.BildanzeigeNeu.Height)}
fk.DrawLines(Pens.Black, Xpoints)
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles Button1.Click
OpenFileDialog1.Filter = "JPG|*.jpg|Bitmap|*.bmp"
If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
BildanzeigeNeu.Image = Image.FromFile(OpenFileDialog1.FileName)
End If
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles Button3.Click
BildanzeigeNeu.Image = SetTransparent(BildanzeigeNeu.Image)
End Sub
Private Function SetTransparent(ByVal vectorImage As Bitmap) As Bitmap
Dim Diff As Integer = Farbabweichung.Text
Dim A As Integer = AktuelleFarbeA.Text
Dim R As Integer = AktuelleFarbeR.Text
Dim G As Integer = AktuelleFarbeG.Text
Dim B As Integer = AktuelleFarbeB.Text
Dim RN As Integer
Dim GN As Integer
Dim BN As Integer
Dim z As Integer
For z = Diff * -1 To Diff
RN = R + z
GN = G + z
BN = B + z
If RN < 0 Then
RN = 0
End If
If RN > 255 Then
RN = 255
End If
If GN < 0 Then
GN = 0
End If
If GN > 255 Then
GN = 255
End If
If BN < 0 Then
BN = 0
End If
If BN > 255 Then
BN = 255
End If
'MsgBox(z & " RN " & RN & " GN " & GN & " BN " & BN)
vectorImage.MakeTransparent(Color.FromArgb(A, RN, GN, BN))
Next
Return vectorImage
End Function
End Class Wäre super, wenn Du mir meinen Fehler nennen könntest bzw. mir kurz den Unterschied zwischen den beiden Methoden erklären könntest.
Vielen Dank
Volker | |
Re: Bild mit Transparente Farbe funktioniert nur mit der langsamen Methode | | | Autor: Christoph1972 | Datum: 17.02.13 20:27 |
| Hi,
kann gut sein das es einen Unterschied gibt. Bei mir macht die Methode genau das was ich von ihr erwarte. Warum das bei dir nicht hinhaut kann ich dir leider nicht sagen und kann es mir auch nicht erklären, dein Code sollte funktionieren!?
Gruß
Christoph
| |
Re: Bild mit Transparente Farbe funktioniert nur mit der langsamen Methode | | | Autor: Volker Bunge | Datum: 22.02.13 20:08 |
| Hallo zusammen,
habe mich heute noch einmal mit meinem Programm befasst.
Da ich leider die Lockbit - Möglichkeit für mein Problem nicht richtig umsetzen kann (Verständnisprobleme), habe ich folgende Möglichkeit gefunden.
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices
Public Class Form5
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles Button1.Click
OpenFileDialog1.Filter = "JPG (*.JPG)|*.jpg|GIF (*.gif)|*.gif|Alle|*.*"
OpenFileDialog1.ShowDialog()
BildAnzeigeNeu.Image = Image.FromFile(OpenFileDialog1.FileName)
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles Button2.Click
PictureBox1.Image = BildAnzeigeNeu.Image
PictureBox1.Refresh()
End Sub
Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As _
System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
If IsNothing(BildAnzeigeNeu.Image) Then Exit Sub
Dim Diff As Byte = Farbabweichung.Text
Dim A As Byte = AktuelleFarbeA.Text
Dim R As Byte = AktuelleFarbeR.Text
Dim G As Byte = AktuelleFarbeG.Text
Dim B As Byte = AktuelleFarbeB.Text
Dim RN As Byte
Dim GN As Byte
Dim BN As Byte
Dim z As Integer
For z = Diff * -1 To Diff
Dim bmp As Bitmap = New Bitmap(BildAnzeigeNeu.Image)
Dim Graph As Graphics = Graphics.FromImage(bmp)
RN = R + z
GN = G + z
BN = B + z
If RN < 0 Then
RN = 0
End If
If RN > 255 Then
RN = 255
End If
If GN < 0 Then
GN = 0
End If
If GN > 255 Then
GN = 255
End If
If BN < 0 Then
BN = 0
End If
If BN > 255 Then
BN = 255
End If
Dim attr As New ImageAttributes
Dim c As Color = Color.FromArgb(0, RN, GN, BN)
' Set the transparency color key based on the upper-left pixel
' of the image.
' Uncomment the following line to make all black pixels transparent:
' attr.SetColorKey(bmp.GetPixel(0, 0), bmp.GetPixel(0, 0))
' Set the transparency color key based on a specified value.
' Uncomment the following line to make all red pixels transparent:
attr.SetColorKey(c, c)
' Draw the image using the image attributes.
PictureBox1.Image = Nothing
Dim dstRect As New Rectangle(0, 0, bmp.Width, bmp.Height)
e.Graphics.DrawImage(bmp, dstRect, 0, 0, bmp.Width, bmp.Height, _
GraphicsUnit.Pixel, attr)
Next
End Sub
Private Sub Form5_Load(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles MyBase.Load
AktuelleFarbeA.Text = 255
AktuelleFarbeR.Text = 220
AktuelleFarbeG.Text = 241
AktuelleFarbeB.Text = 236
Farbabweichung.Text = 0
'invert()
End Sub
end class So wie der Code oben angeben ist, wird die eingestellte Farbe auch super schnell in Transparent geändert.
Sobald aber die Farbabweichung >0 ist, tut sich optisch nichts. Das Programm bleibt bei der Zeile
Dim bmp As Bitmap = New Bitmap(BildAnzeigeNeu.Image)
hängen. Fehlermeldung: Nicht genügend Arbeitsspeicher
Wenn die Schleife einmal durchgelaufen ist, müsste ich doch eigentlich 'nur' das geänderte Bild abspeichern und dieses erneut durchlaufen lassen, oder?
Wenn ja, wie funktioniert dies bzw. was mache ich falsch.
Für ein Code-Bsp. wäre ich Euch sehr dankbar.
Vielen Dank
Volker
Also liegt die Vermutung nahe, dass diese Funktion nur einmal durchlaufen werden kann | |
| Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
|
|
Neu! sevDTA 3.0 Pro
SEPA mit Kontonummernprüfung
Erstellen von SEPA-Dateien mit integriertem BIC-Verzeichnis und Konto- nummern-Prüfverfahren, so dass ungültige Bankdaten bereits im Vorfeld ermittelt werden können. Weitere InfosTipp des Monats TOP Entwickler-Paket
TOP-Preis!!
Mit der Developer CD erhalten Sie insgesamt 24 Entwickler- komponenten und Windows-DLLs. Die Einzelkomponenten haben einen Gesamtwert von 1605.50 EUR...
Jetzt nur 599,00 EURWeitere Infos
|