Graphics.FromImage gibt Fehler bei Bitmap zurück

  • VB.NET

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

    Graphics.FromImage gibt Fehler bei Bitmap zurück

    Hi,

    ich möchte in VB ein 1Bit-Monochromes Bitmap erstellen und dort dann einen Ladebalken zeichnen und diese dann in einer Picturebox anzeigen, die Doppelt so gross als Das Bitmap ist (mit StrechImage und so)

    Mein Momentaner Code:

    VB.NET-Quellcode

    1. Imports System.Drawing.Drawing2D
    2. Public Class Form1
    3. Dim i As Integer
    4. Dim pen1 As New System.Drawing.Pen(Color.Black, 1)
    5. Dim fnt As Font = New Font("Quartz MS", 8)
    6. Dim w As Integer = 128
    7. Dim h As Integer = 64
    8. Dim bmp As New Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format1bppIndexed)
    9. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    10. If i = 90 Then
    11. Me.Close() ' 260 115
    12. Else
    13. i = i + 1
    14. Label1.Text = " " & i & "%"
    15. Dim rect As New Rectangle(25, 5, i, 15)
    16. Using g As Graphics = Graphics.FromImage(bmp) 'Fehler Hier
    17. Dim gradientBrush As New LinearGradientBrush(rect, Color.Black, Color.Black, LinearGradientMode.Horizontal)
    18. g.FillRectangle(gradientBrush, rect)
    19. End Using
    20. PictureBox1.Image = bmp
    21. End If
    22. End Sub
    23. Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    24. Call Draw()
    25. End Sub
    26. Sub Draw()
    27. Using g As Graphics = Graphics.FromImage(bmp) ' Fehler Hier!
    28. Dim fnt As Font = New Font("Quartz MS", 8)
    29. g.DrawString("CPU", fnt, Brushes.Black, 2, 6)
    30. g.DrawRectangle(pen1, 25, 5, 90, 15)
    31. End Using
    32. PictureBox1.Image = bmp
    33. End Sub
    34. End Class

    Der Fehler:
    Ein Grafikobjekt kann nicht aus einem Bild mit einem indizierten Pixelformat erstellt werden.

    Was will mir .NET damit sagen? Ich sehe, das er nicht mit monochrom klar kommt, aber wie kommt er damit klar?

    mfg

    gfc
    Soweit ich das sehe gar nicht. Du kannst keine PixelFormate verwenden, die "Indexed" im Namen haben. Warum ist auch klar, Indexed bedeutet, dass die Farbe nicht durch den Wert des Pixels bestimmt wird, sondern der Wert zeigt auf einen Eintrag in einer Tabelle von Farben.
    Hmm, sonst sehe ich keine 1bit Formate ohne indexed. Wäre es nicht möglich, normale 32bit zu nehmen, und dann nur schwar/weiss zu verwenden und am ende diese dann zu einem monochronem bitmap zu konverten?

    mfg

    gfc
    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.
    Ich weiß nicht, wie du das genau sendest, aber vermutlich als Byte-Array. Von daher wäre es logisch, auch einfach gleich ein solches zu bearbeiten. Du kannst dir das Array in ner Klasse kapseln und dann Get/SetPixel mittels Bitoperationen definieren.

    Das ist ein 2tes Problem. Da mein LCD die Daten in 8Bit-Pakete parallel schreibt und so jede Page abklappert muss ich diese dementsprechend auf dem PC vorbereiten. Wenn ich die Daten der Picture-Box sende, wie werden diese standartmässig versendet? Pixel für pixel nacheinander oder 'parallel' wie beim LCD-Controller?

    (Sry wenn sich der Thread vermischt)

    mfg

    gfc

    gfcwfzkm schrieb:

    Pixel für pixel nacheinander oder 'parallel' wie beim LCD-Controller?
    Ich denke mal Pixel-parallel und Byte-seriell.
    Das sollte aber die Gegenstelle Deiner Kommunikation besser wissen.
    Lies doch mal deren Handbuch oder Internetseite.
    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 Gegenstelle habe ich mit einem ATmega 8zum laufen gebracht, die ist klar definiert. ^^
    Der empfängt jedes Byte und sendet es direkt zum LCD-Display. Habe kein Buffer oder sonstiges mitprogrammiert. Der LCD-Controller geht und 'Bilder' zeigt er auch, insofern diese schon im Programm gespeichert sind. Und da ist das Problem, weshalb ich ja per UART nun die Daten schicken will. Ich gehe einfach die Pixturebox durch (getpixel) und schicke ihm dementsprechend die Werte. Die Hardware steht und läuft schon.

    mfg

    @RodFromGermany
    Dein Zitat ist von dem Teil, wo ich gefragt habe, wie VB mit den Daten umgeht. Wie mein MCU und mein LCD damit umgehen weiss ich schon ^^

    gfcwfzkm schrieb:

    Wie mein MCU und mein LCD damit umgehen weiss ich schon
    Wo ist dann das Problem?
    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!
    Nur noch bei der Übertragung, aber da mach ich mir schon was. Auch wenn ich mich mit Byte-Array nicht so ganz klar komme (Und nun doch die PictureBox als Datenspeicher verwende). Ausser die Übertragungsfunktion läuft schon alles. Wird am Ende ein hübsches sys-info panel ^^ (Mit Menü und allem drum und dran)

    #Erledigt#

    mfg

    gfc
    Bilder
    • lcdmon.PNG

      5,44 kB, 145×122, 1.044 mal angesehen

    gfcwfzkm schrieb:

    Und nun doch die PictureBox als Datenspeicher verwende
    Das solltest Du Dir sofort abgewöhnen.
    Die blanken Daten kommen in ein Array, aufbereitete Daten zur Darstellung in die PicturBox.
    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!
    Hmm, und wenn ich die Daten in die PictureBox zeiche, diese aber nacher wieder als ByteArray einlese und sende, dann wärs ok?

    gfcwfzkm schrieb:

    wenn ich die Daten in die PictureBox zeiche,
    sind doch die Daten nicht verloren. Sie sollten gleich in einem ByteArray vorliegen und feddich. :D
    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!
    Dieses ByteArray verwirrt mich (Ein Grund wieso ich C mag). Byte-Mässig arbeite ich lieber in C. In VB ist das ein richtiger Krampf.

    Ich bin nun soweit, das ich die PictureBox als Bitmap wieder einlese und dort dann Pixel für Pixel Im richtigen LCD-Format durchgehe. Das also nacher die Daten schon fixfertig fürs LCD sind ^^

    VB.NET-Quellcode

    1. Public Sub BitmapToBLCD(ByVal bmp As Bitmap)
    2. Dim x As Integer = 0
    3. Dim y As Integer = 0
    4. Dim calc As Integer = 0
    5. Dim page As Integer = 0
    6. Dim result As Integer = 0
    7. For calc = 0 To ((128 * 64) / 8) - 1
    8. For x = 0 To bmp.Width - 1
    9. For y = 0 To 8 - 1
    10. If bmp.GetPixel(x, y + (8 * page)) = Color.Black Then
    11. result.SetBit(y, True)
    12. Else
    13. result.SetBit(y, False)
    14. End If
    15. Next
    16. TextBox1.Text = TextBox1.Text + result.ToString("2X") 'Zum probieren
    17. Next
    18. page = page + 1
    19. Next
    20. End Sub

    Theoretisch so weit so gut. Jetzt bekomm ich die PictureBox nicht in ein Bitmap kopiert X(
    Dim bmp as New Bitmap(Main.Image, Main.Size) gibt den Fehler "Der Wert darf nicht NULL sein. Parametername: image"

    Aber in der PictureBox ist eine Grafik, wie kann das dann 0 sein?

    Edit:// sonne, habs korrigiert. Jetzt stimmts

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


    Deswegen. Ich will Byte für Byte in der Gewünschten anordnung ausgeben. Deswegen auch das mit dem Calc und dem y. Weil 128x64 auf 1kB an Daten kommt.

    Das mit dem If bmp...: x ist klar, y höhe. Ich will immer 8Bits einlesen. Wenn ich nun aber in die nächste "Page" gehen will, muss diese auch bei y angepasst werden. z.B. von Page 0 auf Page 1, dann müsste y für das 0te Bit 8 betragen.
    @gfcwfzkm: Probier doch mal, eine Bitmap in genau dem Format zu erzeugen, in dem Deine Daten vorliegen:

    VB.NET-Quellcode

    1. Dim bmp = New Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed)
    2. Dim bmpData = bmp.LockBits(rc, System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat)
    3. ' hier kannst Du mit Array-Operationen Deine Werte reinblasen
    4. bmp.UnlockBits(bmpData)
    und dann in eine andere Bitmap reinmalen
    oder
    direkt einem Image zuweisen.
    Musst Du mal probieren.
    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!