SetPixel zu langsam, Librarys helfen nicht

  • VB.NET

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von Crazydrift.

    SetPixel zu langsam, Librarys helfen nicht

    Ich will mir eine Bitmap erstellen. Farben lese ich aus einem Array aus, größe 10.000/10.000.

    Da ich ja eigentlich sonst nichts mit GDI+, Bitmaps uns sonstigem Grafik-Zeugs am Hut habe, hab ich das heute zum ersten mal ausprobiert.
    Da dachte ich mir, "Toll, SetPixel und GetPixel, entspricht meinen Anforderungen.", leider stellte sich das dann als zu langsam heraus.
    Dann habe ich mich informiert und herausgefunden, dass das ganze langsam ist, solange man lockPixels ausführt. Das ganze sah aber sehr kompliziert aus,
    die meisten Beispielcodes waren für C#. Danach binn ich auf die FastGraphicsLibrary hier im Board gestoßen. Sollte das Problem beheben, hat es aber nicht.
    Das Komische ist, es hat an der Geschwindigkeit gar nichts verändert. Falsch mache ich doch nichts daran:

    Quellcode

    1. Pseudocode:
    2. .FromBitmap(Neue Bitmap mit der größe 10.000/10.000)
    3. per .setPixel bearbeiten
    4. .Unlock
    5. die .Bitmap verwenden


    Funktioniert hat es auch, eben nur zu langsam.
    Danach hab ich die FastPixel-Library verwendet, die so ähnlich funktioniert, allerdings wieder das selbe.

    Mfg
    Hi
    warum SetPixel und GetPixel verwenden, wenn man LockBits schon verwendet? Um Performanz zu gewinnen, verwende LockBits mit einem 32bpp-Format o.Ä. und in Kombination mit einem Array oder vorzugsweise in einem unsafe-Kontext in C#. Das geht da übrigens wesentlich einfacher.
    Was willst du denn tun?

    Gruß
    ~blaze~
    Also ich kenn mich ja wie gesagt in diesem Bereich nicht aus, ich wollte eben "nur" Daten in einem riesen Array auf einer Bitmap veranschaulichen. Ich dachte ich schreib da mal schnell ein Programm, aber das geht wohl nicht so einfach. SetPixel ist einfach perfekt für meinen Anwendungsbereich. Ich will eben diese Funktion nutzen, ich dachte ich mach das mit einer Lib schneller, ich wundere mich bloß warum da kein Geschwindigkeitsgewinn rauskommt, die benutzen doch auch die LockBits Technik.
    Edit: Mit der jetzigen Geschwindigkeit braucht ein Durchgang 3 Stunden. :thumbdown:
    Select Case mit 10 Fällen in dem ich den x,y Inhalt des Arrays direkt Prüfe. Inhalt des Array's ist ein Enum. Dann setze ich noch alle 10000 Durchläufe von setPixel einen neuen String in eine Variable. Davor hab ich das jedesmal getan, nun habe ich eine leichte Geschwindigkeitssteigerung. Trotzdem etwas langsam.

    Edit: Gibt es da nicht eine möglichkeit, ein Color-Array zu erstellen und dies dann zu einer Bitmap zu formen?
    Aber echt! xD

    Lockbits ist eigentlich ganz einfach, schau dir mal den Code hier an: msdn.microsoft.com/de-de/library/5ey6h79d.aspx
    Habe das mal so umgebaut, dass du es ganz einfach nutzen kannst:

    VB.NET-Quellcode

    1. Dim sizeX As Integer = 100
    2. Dim SizeY As Integer = 50
    3. Public Function RenderArray() As Bitmap
    4. Dim bmp As New Bitmap(sizeX, SizeY)
    5. Dim rect As New Rectangle(0, 0, bmp.Width, bmp.Height)
    6. Dim bmpData As System.Drawing.Imaging.BitmapData = bmp.LockBits(rect, Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat)
    7. Dim ptr As IntPtr = bmpData.Scan0
    8. Dim bytes As Integer = Math.Abs(bmpData.Stride) * bmp.Height
    9. Dim rgbValues(bytes - 1) As Byte
    10. Dim a, r, g, b As Byte
    11. Dim offset As Integer = 0
    12. For x = 0 To SizeY - 1
    13. For y = 0 To sizeX - 1
    14. 'Hier musst du aus deinem Enum-Wert die Farbe berechnen, also die RGB-Werte für den ArrayEintrag(x,y)
    15. a = 255
    16. r = 255
    17. g = 255
    18. b = 255
    19. rgbValues(offset + 0) = a
    20. rgbValues(offset + 1) = r
    21. rgbValues(offset + 2) = g
    22. rgbValues(offset + 3) = b
    23. offset += 4
    24. Next
    25. Next
    26. System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes)
    27. bmp.UnlockBits(bmpData)
    28. Return bmp
    29. End Function


    Interessant wäre zu wissen, wie du die Enum-Daten in Farben umwandelst. Jenachdem wie du das machst geht dir da viel Zeit flöten (3 Stunden sind sehr lange, bei mir dauert das weiß-färben einer 10.000x10.000 großen bitmap ca. 920ms, also weniger als eine Sekunde. Es muss also an deiner Enum-zu-Farbe-Rechnerei liegen). Poste diesen Teil bitte mal^^ (Da hier alle RGB-Werte = 255 sind ensteht ein weißes Bild)

    lg

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

    1. Wie bereits mehrfach angesprochen: Gib Code, gib Code, gib Code ... ;)

    2. Ich vermute, dass

    2.a. du folgendes machst
    lockbits
    setSinglePixel
    unlockbits
    DAS ist logischerweise langsamer als:
    lockbits
    setAllPixelsInLoop
    unlockbits

    2.b. der Code in der Schleife subperformant ist ...
    Nein das wars nicht. Ich hab pro Pixel noch eine String Variable verändert, nachdem ich das weggelassen habe funktioniert es nun in ca. 10 Sekunden. :pinch:
    Hätte nicht gedacht das das so viel an der Perfornance ausmacht. :wacko:

    Naja, Thema erledigt.

    Mfg