Graphics.FromImage gibt Fehler bei Bitmap zurück

  • VB.NET

Es gibt 36 Antworten in diesem Thema. Der letzte Beitrag () ist von gfcwfzkm.

    @sonne75
    Sowas mache ich manchmal auch, weil es lesbarer sein kann. Iwann fragt man sich nämlich "woher kommt die 1023 ncohmal??" - so sieht man sofort "Ah, das Array hat x*y Elemente, Arrays sind Nullbasierend, darum die -1".

    @gfcwfzkm
    Ich würde ja ein 2-Dimensionales Boolean-Array nehmen (vllt auch eine Enum vom Typ Byte, mit 1 und 0 als Wert kann man später gut shiften) um die Pixel-Daten zu speichern. Dann gibt es eine Methode .toBitmap die das Ganze grafisch darstellt (am besten per Lockbits) und eine Methode .toByteArray die immer 8 Bits zusammenshiftet und als Byte einem Array oder einer Liste added. Die Gegenstelle kann das Bytearray dann zu den einzelnen Bits rekonstruieren.

    Eine Bitmap zum Datenspeichern würde ich nicht benutzen, weil man sich dann mit der Frage welcher Pixel schwarz und welcher weiß ist herumschlagen muss. Natürlich wäre eine Methode .fromBitmap dennoch möglich, vllt zusätzlich. Auch die Daten direkt als Bytearray zu handhaben finde ich umständlich, darum ein 2D-Array aus Boolean/(Byte mit den Werten 0 oder 1).
    Ich glaube die wird eh wegoptimiert. Bei Code geht es in erster Linie um Lesbarkeit.
    Einen Schritt weiter sollte man solche 'hartcodierten' Konstanten garnicht benutzen, sondern sie in Variablen verpacken - z.B. DisplaySize - und mit diesen weiterrechnen. Die Wahrscheinlichkeit ist nunmal sehr hoch, dass man die Werte öfters braucht. Will man eine andere DisplaySize unterstützten kann man überall neue 1023'iger ausrechnen - und wehe man vergisst einen.

    Es heißt im Code selbst gehören nur die Zahlen 1 und 0. Alles andere gehört als globale Variable/Constant deklariert.
    Hmm, ich schau mir Boolean-Array's grad an, sieht gut zum Handhaben aus. Jedoch kann ich dann die System.Drawing nicht mehr direkt damit nutzen, oder? Also ich kann nicht mehr in das Array ein Text "zeichnen" ?

    Mit meiner Aktuellen BitmapToBLCD-Funktion dauert es zu lange, ist also auch leider ein flop :(

    mfg

    gfc

    gfcwfzkm schrieb:

    in das Array ein Text "zeichnen" ?
    What?
    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!
    Das Array stellt ja das Display dar. Zeichnen kannst du nur auf Bitmaps, also brächtest du eine .fromImage-Methode die ein Bild in ein Boolean-Array überführt. An dem Punkt kann man streiten, ob man die Daten nicht doch besser in einer Bitmap 'hinterlegt'.
    Also wäre BooleanArray im endeffekt wieder ein Umweg? Das Problem ist, das ich nicht 1 bis 2 sekunden auf die Daten warten möchte, da ich schon fast eine Sekunde zum übertragen der Daten brauche (1kB Daten, 9600 Baud)
    Dann lege eine Bitmap an, zeichne mit GDI auf sie und lese mit Lockbits die einzelnen Pixel aus, entscheide ob er Schwarz oder Weiß interpretiert werden soll und shifte sie zu Bytes zusammen. Ich schätze mal, dass keine 50ms dafür zusammenkommen (128*64 Pixel Auflösung ist eben nicht viel).
    Ich sehe, das ich auch 1Bit Monochrom haben kann, (New Bitmap(...Indexed)).
    Darin geht jedoch set/getpixel nicht. Kann man die sonst irgendwie "bemalen"?

    gfcwfzkm schrieb:

    Kann man die sonst irgendwie "bemalen"?
    Kopiere dies in eine "normale" Bitmap.
    Hatten wir aber schon.
    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!
    Ja schon. Das nervige ist aber das selbst wenn ich nur mit Schwarz und Weiss male, dass dann weiterhin andere Grautöne im Bild sind -.-
    Bilder
    • test.jpeg

      2,37 kB, 128×64, 269 mal angesehen

    gfcwfzkm schrieb:

    dass dann weiterhin andere Grautöne im Bild sind
    Kannst Du mal einen Datensatz posten?
    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!
    Die Grautöne bekommst du weg indem du z.B.

    VB.NET-Quellcode

    1. g.TextRenderingHint = Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit

    setzt. Musst du mal mit ein verschiedenen Schriftarten durchprobieren, manche kann man recht schlecht lesen.

    gfcwfzkm schrieb:

    Mein Datensatz?
    Sieh Dir mal das an:
    Byte-Array to Bitmap

    VB.NET-Quellcode

    1. Imports System.Drawing
    2. Imports System.Drawing.Imaging
    3. Public Class Form1
    4. Private bmp As Bitmap
    5. Private pixel(256 * 256 - 1) As Byte
    6. Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    7. ' Byte-Array bereitstellen
    8. Dim index = 0
    9. For x = 0 To 255
    10. For y = 0 To 255
    11. pixel(index) = CByte(x)
    12. index += 1
    13. Next
    14. Next
    15. End Sub
    16. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    17. bmp = New Bitmap(256, 256, Imaging.PixelFormat.Format8bppIndexed)
    18. ' eine geeignete Palette bereitstellen
    19. Dim pal As ColorPalette = bmp.Palette
    20. For i = 0 To pal.Entries.Length - 1
    21. pal.Entries(i) = Color.FromArgb(i, i, i) ' Graukeil
    22. Next
    23. bmp.Palette = pal
    24. Dim bmpData = bmp.LockBits(New Rectangle(0, 0, 256, 256), System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat)
    25. Dim ptr As IntPtr = bmpData.Scan0
    26. ' hier werden Deine Byte-Werte in den Bitmap-Speicher reingeblasen
    27. System.Runtime.InteropServices.Marshal.Copy(pixel, 0, ptr, 256 * 256)
    28. bmp.UnlockBits(bmpData)
    29. Dim bmp2 As New Bitmap(256, 256)
    30. Dim gr = Graphics.FromImage(bmp2)
    31. gr.DrawImage(bmp, 0, 0)
    32. Me.PictureBox1.Image = bmp2
    33. End Sub
    34. End Class
    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!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RodFromGermany“ () aus folgendem Grund: Quellcode eingefügt

    gfcwfzkm schrieb:

    Naja, wieder ein riesen umweg. Mein eigentliches Ziel ist es, ein 128x64 Pixel Bild per UART (RS232) zu senden, wobei 1 Pixel 1 Bit gross ist. Dass setzte ich dann auf einem 128x64Pixel LCD wieder zusammen ^^. Da ich nur 'Black' in der Pixturebox verwende, wie kann man dann überprüfen, welche Farbe in dem Pixel grad ist? So könnte ich dann überprüfen, welche Farbe das Pixel hat, 1/0 senden und zum nächsten Pixel gehen.

    Also soweit ich sehe, gibt es Daten, die eine LCD steuern sollen, die zur Kontrolle aber auch auf einem Control anzuzeigen sind.
    Man kann ja problemlos in die Graphics eines Controls zeichnen - ich weiß die ganzen 35 posts nicht, wozu man hier unbedingt eine Bitmap haben will.
    Oder ists tatsächlich so, dass sone LCD direkt von einer 1bpp-indexed Bitmap angesteuert wird?

    ErfinderDesRades schrieb:

    Oder ists tatsächlich so, dass sone LCD direkt von einer 1bpp-indexed Bitmap angesteuert wird?

    Jein. Tatsache ist, dass das Display nur Schwarz/Aus(dunkelgrün) kennt und ich selber meistens direkte Monochrome Bitmaps in den Speicher einprogrammieren, wenn nötig. Was jedoch genau nun drauf kommt kann ich im Microcontroller selber entscheiden. Wenn ich jedoch die Daten schon vom PC aus sende, möchte ich das der Microcontroller selber nix mehr machen muss. Also die Daten empfängt und direkt an das LCD weitergibt. Das mühsame ist, das mein LCD-Display 8Datenleitungen hat. Heisst, das 8bits parallel gesetzt werden. Ich kann es am PC also nicht einfach in nem Stream setzten und das weiterschicken.

    Deswegen möchte ich die Daten am PC vorher für den Transport 'zurechtstutzen'.

    Ich werd mal FreakJNS Tipp verwenden, um die Grautöne loszuwerden und dann Pixel für Pixel überprüfen, welche Farbe dort ist und diese dann senden.

    Hier nebenbei ein Bild von der Hardware (LCD)
    Bilder
    • WP_20130910_002.jpg

      212,5 kB, 720×1.278, 64 mal angesehen

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