Pixel Scan

  • VB.NET

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Ich weis nicht ob ich hier richtig bin :D falls nicht bitte verschieben // komme mit dem "neuen" Forum noch nicht ganz klar - kann auch nur Vb6 auswählen? O.o

    Ich habe ein kleines Problem:

    Ich habe ein Programm geschrieben das ein Bild vom Desktop erstellt , die Pixelfarben durch geht und vergleicht.Allerdings wird es bei mir wohl teils falsch angezeigt o.ä. . Irgendwo ist also ein Fehler und ich weis nicht wo...

    VL.Hat von euch ja jemand eine Idee:

    Spoiler anzeigen

    Quellcode

    1. Option Strict On
    2. Public Class Form1
    3. Dim All As Integer = 0
    4. Dim matches As Integer
    5. Public farbe_1 As Color = Color.Red
    6. Public farbe_2 As Color = Color.Red
    7. Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
    8. Select Case e.KeyCode
    9. Case Keys.S
    10. scaning()
    11. Case Keys.C
    12. Dim c As New ColorDialog
    13. c.ShowDialog()
    14. farbe_2 = c.Color
    15. End Select
    16. End Sub
    17. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    18. Me.Text = My.Computer.Screen.WorkingArea.Width & " " & My.Computer.Screen.WorkingArea.Height
    19. Form2.Show()
    20. End Sub
    21. Private Sub scaning()
    22. All = 0
    23. matches = 0
    24. Dim screenshot As Size = New Size(My.Computer.Screen.WorkingArea.Width, My.Computer.Screen.WorkingArea.Height)
    25. Dim screengrab As New Bitmap(My.Computer.Screen.WorkingArea.Width, My.Computer.Screen.WorkingArea.Height)
    26. Dim g As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(screengrab)
    27. g.CopyFromScreen(New Point(0, 0), New Point(0, 0), screenshot)
    28. g.DrawImage(screengrab, 0, 0)
    29. For x = 0 To My.Computer.Screen.WorkingArea.Width
    30. For y = 0 To My.Computer.Screen.WorkingArea.Height
    31. Me.Text = x & " " & y
    32. All += 1
    33. farbe_1 = screengrab.GetPixel(x, y)
    34. If farbe_1 = farbe_2 Then
    35. matches += 1
    36. End If
    37. Cursor.Position = New Point(x, y)
    38. Next
    39. Next
    40. Label2.Text = "Gesamt: " & All
    41. Label3.Text = "Matches: " & matches
    42. End Sub
    43. End Class

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Thorstian“ ()

    Thorstian schrieb:

    VB.NET-Quellcode

    1. For x = 0 To My.Computer.Screen.WorkingArea.Width
    2. For y = 0 To My.Computer.Screen.WorkingArea.Height
    Machma hinten an beide Zeilen eine - 1 dran, .NET ist Null-basiert.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Mach es so.

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports System.Text.RegularExpressions
    3. Imports System.Runtime.InteropServices
    4. Public Class Form1
    5. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    6. ProcessImage()
    7. End Sub
    8. Public Sub ProcessImage()
    9. 'Screenshot erstellen
    10. Dim input As New Bitmap(SystemInformation.VirtualScreen.Width, SystemInformation.VirtualScreen.Height)
    11. Dim gpcs As Graphics = Graphics.FromImage(input)
    12. gpcs.CopyFromScreen(0, 0, 0, 0, input.Size)
    13. gpcs.Dispose()
    14. 'LockBits
    15. Dim bmpData As System.Drawing.Imaging.BitmapData = input.LockBits(New Rectangle(0, 0, input.Width, input.Height), Drawing.Imaging.ImageLockMode.WriteOnly, input.PixelFormat)
    16. Dim ptr As IntPtr = bmpData.Scan0
    17. Dim bytes As Integer = Math.Abs(bmpData.Stride) * input.Height
    18. Dim rgbValues(bytes - 1) As Byte
    19. Marshal.Copy(ptr, rgbValues, 0, bytes)
    20. 'Durchlaufen
    21. Dim offset As Integer = 0
    22. For y = 0 To input.Height - 1
    23. For x = 0 To input.Width - 1
    24. 'Colorobjekt erzeugen (weiß nicht ob es so richtigrum ist)
    25. Dim num As Integer = (rgbValues(offset + 0) >> 16) Xor &HFF
    26. Dim num2 As Integer = ((rgbValues(offset + 1)) >> 8) Xor &HFF
    27. Dim num3 As Integer = (rgbValues(offset + 2) Xor &HFF)
    28. Dim clr As Color = Color.FromArgb(num3, num2, num)
    29. 'Hier jetzt deine Sachen da prüfen
    30. offset += 3 'BytesPerPixel!
    31. Next
    32. Next
    33. 'UnlockBits
    34. Marshal.Copy(rgbValues, 0, ptr, rgbValues.Length)
    35. input.UnlockBits(bmpData)
    36. End Sub
    37. End Class
    Danke ich teste es;aber kannst du es noch genauer erklären?Das Tutorial lese ich mir momentan auch noch durch

    Wie kann ich denn Farben vom Color dialog in RGB Umwandeln?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Thorstian“ ()

    Kla :)
    Also ich denke das mit dem Screenshot sollte klar sein. Das ist mit .CopyFromScreen() jetzt nicht ganz so schön.
    Besser nutzt man da die API-Funktionen. Siehe hier stackoverflow.com/questions/89…of-a-specific-application (2. Antwort)
    Anhand der erzeugten Bitmap rufst du die Methode .LockBits() auf. Diese gibt ein BitmapData-Objekt zurück, welches du speicherst. Im Prinzip wird die Bitmap im Systemspeicher gesperrt.
    Anschließend lädst du die Daten in ein Array. Die Farbwerte deiner Bitmap sind also jetzt in Form von Byte gespeichert.
    Dabei ist die Reihenfolge BGR(A).
    Der Bitshift ist überflüßig sehe ich gerade. Das brauch man, wenn man von der ARGB-Value zu den Farbwerten will.
    Du erzeugst also aus deinen Werten ein Color-objekt und kannst damit arbeite.
    Zum Schluss wird das ganze "zusammengefügt"

    LaMiy schrieb:

    VB.NET-Quellcode

    1. Dim num As Integer = (rgbValues(offset + 0) >> 16) Xor &HFF
    2. Dim num2 As Integer = ((rgbValues(offset + 1)) >> 8) Xor &HFF
    3. Dim num3 As Integer = (rgbValues(offset + 2) Xor &HFF)
    Wenn Du alle anderen Bits gelöscht haben willst, musst Du And &HFF machen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    So.

    VB.NET-Quellcode

    1. Using clr As New ColorDialog()
    2. If clr.ShowDialog() = Windows.Forms.DialogResult.OK Then
    3. MessageBox.Show(clr.Color.ToArgb().ToString())
    4. End If
    5. End Using

    RodFromGermany schrieb:

    Wenn Du alle anderen Bits gelöscht haben willst, musst Du And &HFF machen.
    So ist's schon richtig glaube ich. In C++ ist's der &-Operator. Aber an dieser Stelle braucht man das mit dem Bitshift gar nicht. Hatte mich nur vertan.

    Thorstian schrieb:

    an einer Koordinate
    Mach mal den inversen Test:
    Setz ein Pixel auf rot oder so.
    Da siehst Du zumindest, ob die Koordinaten stimmen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @Thorstian Hast du auch den Bitshift rausgenommen?

    VB.NET-Quellcode

    1. '...
    2. Dim offset As Integer = 0
    3. For y = 0 To input.Height - 1
    4. For x = 0 To input.Width - 1
    5. 'Colorobjekt erzeugen
    6. Dim b As Integer = rgbValues(offset + 0)
    7. Dim g As Integer = rgbValues(offset + 1)
    8. Dim r As Integer = rgbValues(offset + 2)
    9. Dim clr As Color = Color.FromArgb(r, g, b)
    10. 'Hier jetzt deine Sachen da prüfen
    11. offset += 3 'BytesPerPixel!
    12. Next
    13. Next
    14. '...
    ist es auch möglich aus den x und y Werten wieder eine Koordinate auf dem Bildschirm herzustellen also zB eine List of Points wo sich die Punkte befinden?Dann könnte ich zB die bitmap input zeichnen lassen und ganz doof alle Pixel die zB schwarz sind (0,0,0) mit rot übermalen lassen

    Habe es ausprobiert aber die Koordinaten stimmen nicht überein sondern sind verzerrt