Probleme mit FastGraphicsLib

  • VB.NET

Es gibt 30 Antworten in diesem Thema. Der letzte Beitrag () ist von imax2010.

    Probleme mit FastGraphicsLib

    Hallo,

    ich beschäftige mich seit einer Zeit mit VB (Visual Studio 2010) und habe die DLL gefunden.
    Und zwar möchte ich die Funktion FindPixel nutzen und mir in einem Bild (Testbild mit nur einem schwarzen Pixel) die Position von diesem ausgeben lassen.
    Zudem möchte ich die Anzahl der Pixel zählen. Die Googlesuche hat mir jedenfalls nichts gebracht außer rumprobiere (und keine Funktion).
    Ich scheitere aber dort wo ich den Wert (x/y) in der Textbox anzeigen will. Meistens bekomme ich in der Textbox folgendes: "System.Drawing.Point[]" oder nur eine leere.

    Viele Zeilen hat das Programm nicht.
    Hier die Zeile wo ich den Wert in eine Variable speichern will und dann in die Textbox laden:

    VB.NET-Quellcode

    1. Dim p As Array = fg.FindPixel(Color.Black, 1)
    2. TextBox1.Text = p.ToString

    Deklaration und so stimmt schon da ich die aus dem oberen DLL-Link habe.
    Hoffe jmd kann mir helfen und so mal mein Wissen erweitern.

    Mfg
    Peter

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „imax2010“ ()

    Mir fällt gerade noch was ein:

    VB.NET-Quellcode

    1. Dim b as New Point(20,30)
    2. textbox1.text = b.point.X & b.point.Y


    dann gehts. Es werden X und Y angezeigt. Mach ich statt 20,30 s0:

    VB.NET-Quellcode

    1. Dim b as New Point(fg.FindPixel(Color.Black, 1))

    dann kommt irgendeine Meldung, dass das Array nicht in Integer konvertiert werden kann.


    (wollte oben das editen aber ging nicht: mein browser sagt: Seite kann nicht angezeigt werden schon seit ner halben stunde.)
    Hallo,

    (habs nicht getestet)

    VB.NET-Quellcode

    1. Dim pixel As New List(Of Point)
    2. For Each p As Point In fg.FindPixel(Color.Black,1)
    3. pixel.Add(p)
    4. Next
    5. For i = 0 To pixel.Items.Count
    6. ListBox1.Items.Add(pixel.Items.Item(i).X & pixel.Items.Item(i).Y)
    7. Next


    Dafür brauchst du anstatt einer TextBox eine ListBox einfügen.

    MFG

    Alex-Digital :D
    ~ Alex-Digital :D

    if(!Internet.VBP.Get<User>("Alex-Digital").IsOnline) this.Close(); :D
    Hallo,

    danke erstmal für deine Antwort. Ein Teil scheint zu funktionieren aber ich bekomm für jeden:

    VB.NET-Quellcode

    1. pixel.Items.xxxx

    einen Fehler:

    VB.NET-Quellcode

    1. Fehler 1 "Items" ist kein Member von "System.Collections.Generic.List(Of System.Drawing.Point)". C:\Users\xxx\Documents\Visual Studio 2010\Projects\PixelFinder\PixelFinder\Form1.vb 21 22 PixelFinder
    2. Fehler 2 "Items" ist kein Member von "System.Collections.Generic.List(Of System.Drawing.Point)". C:\Users\xxx\Documents\Visual Studio 2010\Projects\PixelFinder\PixelFinder\Form1.vb 22 32 PixelFinder
    3. Fehler 3 "Items" ist kein Member von "System.Collections.Generic.List(Of System.Drawing.Point)". C:\Users\xxx\Documents\Visual Studio 2010\Projects\PixelFinder\PixelFinder\Form1.vb 22 56 PixelFinder


    //Edit:

    Man muss das so schreiben dann gibts keine Errors:

    VB.NET-Quellcode

    1. For i = 0 To pixel.Count
    2. ListBox1.Items.Add(pixel.Item(i).X & pixel.Item(i).Y)
    3. Next


    Jedoch bekomm ich jetzt beim drücken des Buttons:
    "Der Index lag außerhalb des Bereichs. Er muss nicht negativ und kleiner als die Auflistung sein.
    Parametername: index"

    Jmd eine Idee warum der Index jetzt außerhalb des Bereichs liegt?


    Mfg
    Peter

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

    Ich hab das jetzt so gelöst:

    VB.NET-Quellcode

    1. Dim fg As FastGraphicsLib.FastGraphics = FastGraphicsLib.FastGraphics.FromBitmap(PictureBox1.Image)
    2. Dim p As Array = fg.FindPixel(Color.Black, 10)
    3. If p.Length > 0 Then
    4. For Each a As Point In fg.FindPixel(Color.Black, 10)
    5. ListBox1.Items.Add(a.X)
    6. ListBox2.Items.Add(a.Y)
    7. Next
    8. fg.Unlock()
    9. Else
    10. TextBox1.Text = "kein Punkt gefunden"
    11. fg.Unlock()


    Jedoch stimmt die Anzahl nicht bei (in Paint) 20x20px sagt mir die Lib es sind insegsamt 296px aber das kann ja nicht stimmen!
    Zudem kann man nicht einen Pixel allein auslesen es müssen mindesten (nach testen ca.)10px sein sonst gibt es keine Koordinaten zurück.
    Gibt es eine andere zuverlässigere Methode Pixel einer Farbe zu zählen?
    Kannst es ja mal mit meiner Lib probieren.
    Pixelmagic - Eine Lib zur Bildbearbeitung

    Mit diesem Code:

    VB.NET-Quellcode

    1. Dim myBMP As New Pixelmagic.FastBmp(DEINE_BITMAP)
    2. Dim Toleranz As Integer = 2 'Alle Pixel mit einem Unterschied von 2 werden mit aufgezählt
    3. Dim myList As New List(Of Point)
    4. myList = Await myBMP.findAllPixel(Color.Red, Toleranz)
    5. myBMP.Unlock()

    Dann stehen in myList alle Punkte drin, zumindest sollten sie :D
    Danke für die Antwort:

    VB.NET-Quellcode

    1. Dim myBMP As New Pixelmagic.FastBmp(PictureBox1.Image)
    2. Dim Toleranz As Integer = 2 'Alle Pixel mit einem Unterschied von 2 werden mit aufgezählt
    3. Dim myList As New List(Of Point)
    4. myList = myBMP.findAllPixel(Color.Black, Toleranz)
    5. myBMP.Unlock()

    Hier bekomm ich den Fehler(beim unterstrichenen)

    VB.NET-Quellcode

    1. Fehler 1 Der Wert vom Typ "System.Threading.Tasks.Task(Of System.Collections.Generic.List(Of System.Drawing.Point))" kann nicht in "System.Collections.Generic.List(Of System.Drawing.Point)" konvertiert werden. C:\Users\xxx\Documents\Visual Studio 2010\Projects\PixelFinder\PixelFinder\Form1.vb 34 18 PixelFinder


    Und für was ist das Await (da es nicht deklariert ist)?
    Await sorgt dafür, dass auch bei großen Bildern dein Programm nicht einfriert, da die Methode asynchron läuft.

    Deshalb musst du die Methode, in die du den Code reingeschrieben hast noch als async markieren:

    Aus

    VB.NET-Quellcode

    1. Public Sub Muell

    wird

    VB.NET-Quellcode

    1. Public Async Sub Muell
    @Alex-Digital
    Doch. Als Operator.

    Man wendet den Await-Operator zu einem Operanden in einer asynchronen Methode oder einem Lambda-Ausdruck, die Ausführung der - Methode aufzunehmen, bis die erwartete Aufgabe ausführt. Die Aufgabe repräsentiert die derzeit ausgeführte Arbeit.
    Ok hab ich jetzt installiert und erhalte auch keine Fehler mehr außer wenn ich es debugge:
    Sobald ich den Button drücke kommt: "Ein Aufrufziel hat einen Ausnahmefehler verursacht."
    Der Code ist der von Telcrome hier aus dem Thread
    Also hab das jetzt mit bmp.GetPixel() gemacht da es einwandfrei funktioniert. FastGraphicsLib rechnet falsch bzw. richtig wenn das Bild die Richtige auflösung hat.
    @Telcrome ich werds nochmal probieren vlt. fin ich selber den Weg


    Danke trotzdem an alle für ihre Hilfe

    Mfg
    Peter

    programmer71 schrieb:

    Nein das geht mit Async CTP auch dann in VB 2010. Musst du halt extra runterladen. Standardmäßig ist es erst bei 2012 enthaten.
    Dann aber bitte nicht vergessen, dass man die Binarys der MS-CTPs nicht weitergeben darf (steht in deren Lizenzbedingungen). Um TAP unter VS2010 zu verwenden, ist mir meine Möglichkeit bekannt, bei der man am Ende die Assembly mitleifern kann. Du kannst aber VS2012 mit .NET 4.0 verwenden (ohne Async CTP). Undzwar gibt es dafür das Async Targeting Pack - einfach via NuGet im Projekt installieren.

    Ich habe hier eine modular aufgebaute Library, die du verwenden kannst:
    github.com/nikeee/pixlib
    Ich entwickle aber noch daran. Es fehlen u. A. noch 2 Scannertypen, die du wahrscheinlich nicht brauchen wirst. Der normale Pixelfinder funktioniert einwandfrei. Wenn ich sie komplett fertig habe, kann ich die ja in den Showroom für weitere Sprachen stellen.
    Verwenden könntest du es so:

    VB.NET-Quellcode

    1. Using provider As New FastBitmapPixelProvider(bmp) ' Der geht über LockBits, die Slow-Variante geht über normale Get/SetPixel-Methoden
    2. Dim scanner As new DefaultScanner(provider )
    3. Dim pixels As IEnumerable(Of Pixel) = scanner.FindPixels(color, tolerance)
    4. Dim colors() as Color = pixels.Select(Function(p) p.Color).ToArray()
    5. End Using

    Vorteile:
    - Toleranzscan mit mehr Möglichkeiten (Farben ignorieren/verschiedene Toleranzwerte für verschiedene Farbkanäle)
    - Verwendung von IEnumerable(Of T), was für die LINQ recht praktischt ist
    - Jedes öffentlich zugreifbare Element ist mit XML-Kommentaren versehen (eine Sandcastle-Seite kommt auch noch)

    Nachteile: Momentan kein Multithreading, da ich erstmal mit den UnitTests fertig werden muss.

    Eine etwaige Übersicht der Funktionen findest du hier:
    github.com/nikeee/pixlib/blob/…ysis/IGetPixelProvider.cs
    github.com/nikeee/pixlib/blob/…pulation/IPixelScanner.cs
    Von meinem iPhone gesendet
    Sry hab aber grad Probleme mit deiner Lib @nikeee13:

    Ich muss color und tolerance bei scanner.FinPixel deklarieren oder? Wenn ich das mache und ich es mir anzeigen lassen will dann passiert nicht.
    Zum hinzufügen der Punkte in die Tabelle hab ich das las schleife verwendet:

    VB.NET-Quellcode

    1. For Each Pixel In pixels

    stimmt das?

    Und kannste mir nur grob erklären was das "colors()" macht?

    Danke für die Hilfe hier!
    Mfg
    Peter

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „imax2010“ () aus folgendem Grund: Post war falsches Forum

    Du kannst sie zum Beispiel so verwenden:

    VB.NET-Quellcode

    1. Dim color as Color = Color.White
    2. Dim tolerance as Mew ColorTolerance(10, True)
    3. For each pixel in scanner.FindPixels(color, tolerance)
    4. Debug.WriteLine("Found Pixel: " & pixel.ToString())
    5. Next
    Von meinem iPhone gesendet

    VB.NET-Quellcode

    1. For Each pixel In scanner.FindPixels(color, tolerance)
    2. Debug.WriteLine("Found Pixel: " & pixel.ToString())
    3. PInfo.Text = pixel.ToString
    4. Next


    wenn ich das Teste (pinfo ist meine textbox) dann steht in der Debug ausgabe und in der Textbox steht "Found Pixel: System.Drawing.Analysis.Manipulation.Pixel"

    Edit:

    Wenn ich 2x den Code ausführe dann kommt: "Ungültige Parameter:" bei BitmapPixelProvider.cs (

    VB.NET-Quellcode

    1. Size = bitmap.Size;
    )

    Edit 2:

    Mein Code:

    VB.NET-Quellcode

    1. Dim bmp As Bitmap = CType(PictureBox1.Image, Bitmap)
    2. Using provider As New FastBitmapPixelProvider(bmp)
    3. Dim scanner As New DefaultScanner(provider)
    4. Dim color As Color = color.Black
    5. Dim tolerance As New ColorTolerance(10, True)
    6. For Each pixel In scanner.FindPixels(color, tolerance)
    7. Debug.WriteLine("Found Pixel: " & pixel.ToString())
    8. PInfo.Text = pixel.ToString
    9. Next
    10. End Using
    Da du die Bitmap aus einer Picturebox holt und es sich bei Bitmap um einen Refereztypen handelt, wirst du eine Exception bekommen.

    Warum?
    Weil die Bitmap mit dem Provider disposed wird, sobald der Using-Block zu ende ist.

    Lösung:
    Im Konstruktor des Providers kannst du angeben, dass die Bitmap nicht mit disposed werden soll, wenn der Provider disposed wird.
    Sieht dann so aus:

    VB.NET-Quellcode

    1. New FastBitmapPixelProvider(bmp, False)


    Alternativ kannst du auch mit einer Kopie der Bitmap arbeiten.

    imax2010 schrieb:

    Wenn ich 2x den Code ausführe dann kommt: "Ungültige Parameter:"
    Das wird ebenfalls daran liegen, dass die Bitmap schon disposed ist. Die Lösung von Oben sollte dort auch funktionieren.
    Von meinem iPhone gesendet