Bitmap-Farbmanipulation zu langsam

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von Theckwolf.

    Bitmap-Farbmanipulation zu langsam

    Hallo zusammen,

    folgende Situation:

    ich grabbe von einer Kamera kontinuierlich Graustufenbilder (bis zu 1280x1024 Pixel bei 25fps) und zeige diese in einer Picturebox an.

    Dazu möchte ich je nach Grauwert (0-255), die jeweiligen Pixel entsprechend einfärben - sozusagen eine Farbpalette drüber legen).

    Beispiel:

    R: 128
    G: 128
    B: 128

    wird z.B. zu:

    R: 255
    G: 0
    B: 0

    Folgende Probleme dabei:
    - Sobald man die SizeMode-Property der Picturebox auf Zoom oder StretchImage setzt, ruckelt das Ganze merklich
    - Anscheinend dauert das Einfärben zu lange, da man vor allem bei maximaler Auflösungen das normale Graubild + zusätzlich von oben nach unten flackernde Farbbilder sieht, die jedoch nicht vollständig sind.

    Das Grabben und Darstellen wird in verschiedenen Threads durchgeführt.
    Die Farbpalette steckt in 3 Byte-Arrays (0..255) für den jeweilgen Rot-, Grün- bzw. Blau-Wert.

    Anbei mein Code aus dem UpdateUI-Thread, in dem ich auch die Einfärbung durchführe:

    Quellcode

    1. Private Sub UpdateUI(sender As Object, e As ProgressChangedEventArgs)
    2. Dim Bitmap As Bitmap = cameraimage.bitmap
    3. Dim rect As Rectangle
    4. rect.X = 0
    5. rect.Y = 0
    6. rect.Width = Bitmap.Width
    7. rect.Height = Bitmap.Height
    8. Dim bmpData As System.Drawing.Imaging.BitmapData = Bitmap.LockBits(rect, Drawing.Imaging.ImageLockMode.WriteOnly, Bitmap.PixelFormat)
    9. Dim ptr As IntPtr = bmpData.Scan0
    10. Dim bytes As Integer = Math.Abs(bmpData.Stride) * Bitmap.Height
    11. Dim rgbValues(bytes - 1) As Byte
    12. System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes)
    13. For counter As Integer = 2 To rgbValues.Length - 1 Step 3
    14. Dim x As Byte = rgbValues(counter)
    15. rgbValues(counter) = PaletteEntriesR(x)
    16. rgbValues(counter - 1) = PaletteEntriesG(x)
    17. rgbValues(counter - 2) = PaletteEntriesB(x)
    18. Next
    19. 'Unlock
    20. System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, rgbValues.Length)
    21. Bitmap.UnlockBits(bmpData)
    22. pictureBox1.Image = Bitmap
    23. End Sub


    Gibt es die Möglichkeit, das Bild nur dann zu "malen", wenn es vollständig eingefärbt wurde? Dann ruckelt es zwar, aber es flackert nicht mehr.

    Danke schonmal.

    Theckwolf
    erst malen (im hintergrund) und dann anzeigen...hab das mal an der schule mit java gemacht

    also du malst dein Bild über das Foto und wenn das fertig ist zeigst du es erst an

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

    Nein, wenn die Auflösung z.B. 900*800 beträgt, schaffe ich 25fps ohne flimmern / flackern.
    bei 1280*960 sind 15fps noch ok,aber sobald ich auf 20 oder 25fps hoch gehe, flimmerts wieder.

    Wenn ich das Ganze bei der vollen Auflösung 1280x1024 und 25fps durchführe, zeigt er überhaupt kein Bild mehr an.

    Ohne Einfärben (nur Darstellung des Original-Graubilds) bekomme ich ein Bild, das aber keine 25fps sondern nur noch gefühlte 10fps hat.

    Edit:

    Ich teste gerade GdipEffects, aber ich habe noch keine Ahnung, wie ich damit Pixelfarben manipulieren kann (Blur aus dem Beispiel funktioniert)

    Edit2:

    Versuche es gerade mit "ColorModifier" analog zu Blur, bekomme das Ganze aber nicht implementiert. :(

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

    Mit dem Einfärben hatte ich auch Probleme, versuch mal mit ColorMatrix zu arbeiten, funktioniert sehr schnell.
    Auf der Suche nach Coding-Kursen auf Lence.at

    Theckwolf schrieb:

    Graustufenbilder
    Weise denen eine Palette zu.
    Gugst Du ColorPalette.
    Mach Die ein 256er Color-Array, fülle das mit Deinen Farben.
    Nimm eine Bitmap, hole Dir deren Palette-Eintrag vom Typ ColorPalette,
    gib dem die richtige Dimension (256) und weise den einzelnen Einträgen Deine Color-Werte zu.
    Feddich.
    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!

    RodFromGermany schrieb:

    Weise denen eine Palette zu.
    Gugst Du ColorPalette.
    Mach Die ein 256er Color-Array, fülle das mit Deinen Farben.
    Nimm eine Bitmap, hole Dir deren Palette-Eintrag vom Typ ColorPalette,
    gib dem die richtige Dimension (256) und weise den einzelnen Einträgen Deine Color-Werte zu.
    Feddich.


    Die Graustufenbilder sind normale Bitmaps 24bpp mit z.B. R,G,B: 192,192,192.

    Quellcode

    1. backImage = New Bitmap("c:\Test.bmp")
    2. Dim palette As ColorPalette = backImage.Palette
    3. Dim entries() As Color = palette.Entries


    Beim Abrufen der Palette ist diese leer ?! (entries hat keine Einträge)

    Theckwolf schrieb:

    24bpp
    Da geht das nicht, die müsstest Du nach Gray8 konvertieren.
    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!
    Hi
    Die von RodFromGermany vorgeschlagene color palette macht wenig Sinn, wenn du keine indizierende (indexierte?) Bitmap hast, was wiederum ggf. sogar Sinn machen würde, auch wenn dadurch andere Probleme entstünden, wenn ich mich richtig erinnere (war glaub' ich beim Zeichnen problematisch).
    Hast du schon mal überlegt, direkt die Grafikkarte über DirectX oder OpenGL zu verwenden, wenn der Vorschlag von Gonger96 nicht ausreicht? Das ist über pixel shading sehr einfach zu realisieren.

    Viele Grüße
    ~blaze~
    Hab grad gemerkt, dass ich die Rohbilder der Kamera anstt in 24bpp auch in 8bpp konvertieren kann, was bei Graustufen natürlich locker langt und sie somit auch automatisch ne Palette haben...

    Jetzt geht die Einfärbung über die Paletteneinträge wunderbar schnell.

    Danke euch!