Bild zu Bytes

  • VB.NET
  • .NET 5–6

Es gibt 44 Antworten in diesem Thema. Der letzte Beitrag () ist von -Franky-.

    Danke für die Eindrücke.

    Warum brauche ich das:
    Ich habe hier ein Problem mit einem Drucker, etwas älteres Modell. Der soll wohl auch Bilder (als Bilder) speichern und drucken können. Jedoch das habe ich noch nicht hinbekommen.
    Was funktioniert ist aber Bilder (als Text) zu speichern und zu drucken. Der druckt nur schwarz weiß und macht im Endeffekt das umgekehrte "1" wird zu nem schwarzen punkt und "0" bleibt frei. Die Position kommt über Zeile und Spalte.
    Naja also ich habe Bilder, die ich drucken möchte, aber keinen Code. Wo krieg ich den Text also her? Na da gibt es auch Software zu dem Drucker, allerdings aus 1995. Die macht quasi fast das Gleiche: Bild zu Text.
    Nur ist das 1. unschön zu bedienen und
    2. die Bilder für den Input müssen schon von vornherein schwarzweiß sein und ein bestimmte Dateiformat haben, das heißt ich konvertiere vor dem konvertieren schon mindestens einmal.

    @-Franky- Was die Berechnung der Pixelposition angeht, bei 24bpp muss man 3*8 bytes nehmen und bei 32bpp 4*8. Ich sehe da keinen Unterschied in der Einfachheit.
    @ErfinderDesRades Mir ist zu den PixelFormaten gar nichts bekannt. Ich probier das 1bpp mal aus. Ich hätte gedacht ein Bild hat ein PixelFormat und wenn ich da was anderes festlege, kommt Murks bei raus. Aber anscheinend konvertiert er da automatisch.

    Wofür brauche ich das UnlockBits? Ich weiß LockBits sagt mir den Zeiger, wo die Bilddaten liegen. Nach der Konvertierung ist das Programm ja fertig, da sind die Bilddaten dann eh weg, oder?
    @-Franky- @exc-jdbi
    Color.GetBrightness kommt eine Komponente der Farbe im HSV-Farbraum raus, hab ich mal was zu verzapft: Der HSV-Farbraum
    @Haudruferzappeltnoch Es wird erst mal Zeit, dass Du das erläuterst. Das, wovon Du sprichst, ist kein Text, sondern die "besondere String-Repräsentation" eines Bildes.
    Du willst also eine Matrix aufbauen, wo jeder Wert einem Drucker-Pixel entspricht, was auch immer "Wert" sein mag.
    Ich schlage Dir folgenden Weg vor:
    Erforsche, wie die Kommunikation mit diesem Dreucker funktioniert und dann machen wir da ein schönes Progrämmchen draus.
    Und:
    Was bedeutet es, dass der Drucker Bilder speichern können soll?
    Gibt es zu diesem Drucker eine genaue Bezeichnung?
    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!
    @Haudruferzappeltnoch
    Sieht das Ergebnis überhaupt gut aus? Vielleicht ein kleiner Alternativ-Vorschlag:
    Wieso nicht einfach Image2ASCII und das dann drucken?

    Was du machen kannst ist folgendes: Das Bild nehmen, in ein Graubild umwandeln, anschließend die Helligkeit des Pixels (0-255) auf 255, oder weniger Chars (z.B. auch nur 1 und 0) mappen und es in ein StringBuilder "appenden". Jedes Mal, wenn die Bildzeile endet, ein AppendLine ausführen.

    Ansonsten musst du halt einen guten Treshold finden, um ein gutes Binärbild zu generieren.
    Und Gott alleine weiß alles am allerbesten und besser.
    Zebra S4M.
    Die Kommunikation mit dem Drucker ist nicht das Problem. Das funktioniert ja schon ewig, ist wie gesagt bissle älter.
    Der Drucker will eine besondere String-Repräsentation" eines Bildes. Die zu bekommen war mir bisher zu umständlich, daher wollte ich selber was basteln.
    Ja die Zebra Drucker können auch Bilddateien speichern, also unkonvertiert, das habe ich bei der "Erforschung" herausgefunden. Software gibt es da ja auch für, die das können soll, das ist heute aber alles zu modern oder so. Also das funktioniert nicht, bzw. ist ne ganze Ecke komplizierter, wie auch immer ich kriegs nicht hin. Und brauch ich jetzt ja auch nicht mehr dank dieser neuen Konvertierung
    ^ Da gibt es nichts zu erläutern, darum soll es ja nicht gehen. Das war nur der Hintergrund für exc-jibi und Franky. Lasst uns beim Code bleiben.
    Ich habe in Post 6 auch "bitartige Reprsäsentation" geschrieben, aber "Text" ist halt kürzer.

    Für mich wäre noch das UnlockBits relevant zu klären

    Das Ergebnis sieht gut aus, diese Textdateien hatte ich ja vorher auch schon. Nur war der Weg sie zu bekommen sehr umständlich.

    Image2ASCII finde ich nicht ohne weiteres, worauf basiert das?

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    @BitBrösel
    Was Du vorschlägst, entspricht fast dem 1bppIndexed-Format. 8 Pixel in einem Byte wobei ein Bit (Index) auf die Farbe in der Palette zeigt. Ach, das was Du meinst gibt es auch schon als Dateiformat. PGM oder PBM. ;)
    de.m.wikipedia.org/wiki/Portable_Anymap
    Mfg -Franky-
    @Haudruferzappeltnoch
    Da waren ja noch ein paar Fragen von Dir offen. UnlockBits entsperrt den zuvor per LockBits gesperrten Speicherbereich der Bitmap. Ungetestet: Es wäre daher möglich das ohne UnlockBits der Speicherbereich nicht Aufgeräumt werden kann. Ist doch nur eine Zeile Code mehr.

    Image2ASCII ist ein Verfahren mit dem ein Farbbild in ASCII-Zeichen konvertiert wird. Jedes ASCII-Zeichen stellt dabei einen Helligkeitswert dar. Siehe auch hier: en.m.wikipedia.org/wiki/ASCII_art

    Falls Du noch irgendwann Farbbilder entsprechend konvertieren möchtest, nimm nicht die einfachste Methode um ein Farbbild in ein S/W-Bild zu konvertieren. Bessere Ergebnisse liefert Dir zB das ErrorDiffusion-Verfahren. en.m.wikipedia.org/wiki/Error_…as%20other%20applications Kann man selbst programmieren, kann man mit Hilfe von WIC oder mit ein wenig Reflection und GDI+APIs (die nicht im FrameWork enthalten sind) erledigen lassen. Darüber hinaus gibt es noch andere Verfahren die andere Ergebnisse beim konvertieren von Farbbildern zu S/W-Bilder liefern.
    Mfg -Franky-

    Haudruferzappeltnoch schrieb:

    Im Tutorial, sieht es halt so aus
    Bei Unklarheiten empfehle ich zuerst, in der Microsoft Dokumentation nachzusehen:
    docs.microsoft.com/de-de/dotne…?view=dotnet-plat-ext-6.0
    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!
    @Haudruferzappeltnoch Ein Bild, das in einer Bitmap-Instanz hinterlegt ist, ist kein eigentliches NET-Objekt.
    Der dahinter liegende Speicher wird vom Betriebssystem verwaltet.
    Windows kann Speicherinhalte nach seinem Ermessen hin- und her schieben.
    Damit beim hin- und her schieben Dein Zugriffs-Pointer nicht rausgeschoben wird, kann man Windows sagen, dass der Bildspeicher nicht verschoben werden soll.
    Dies muss ordentlich organisiert werden, also Start mit LockBits und Ende mit UnlockBits.
    So ist gesichert, dass Dein Zugriff auf den Bildspeicher so erfolgt, wie Du Dir es vorstellst.
    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!
    Also ich habe jetzt ein wenig rumprobiert mit den PixelFormats

    Je nach Bildbreite bekomme ich andere Ergebnisse. 24bpp muss anscheinend die Bytes pro Zeile auffüllen bis es durch 4 teilbar ist. Das habe ich noch nicht ganz verstanden

    1bppIndexed funktioniert da ganz verständlich. Da muss ich die Bytes aber noch auseinanderzuppeln, weil da ja schon 8 Pixel drinstecken. Und der wendet bei Farben auch andere Regeln an, also gehen da auch nur schwarzweiß Bilder als Input

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

    @Haudruferzappeltnoch

    Haudruferzappeltnoch schrieb:

    24bpp muss anscheinend die Bytes pro Zeile auffüllen bis es durch 4 teilbar ist. Das habe ich noch nicht ganz verstanden

    Deswegen sag ich ja, verwende für LockBits das 32bppARGB Format. Macht das ganze einfacher. Die Breite einer Bildzeile muss immer durch 4 teilbar sein. Selbst bei einem 1bppIndex mit nur 1x1 Pixel ist die Bildzeile = 4 Bytes. Ansonsten: Die Breite einer Bildzeile gibt Dir der Stride-Wert zurück.
    Mfg -Franky-

    Haudruferzappeltnoch schrieb:

    24bpp muss anscheinend die Bytes pro Zeile auffüllen bis es durch 4 teilbar ist. Das habe ich noch nicht ganz verstanden
    Das hat was mit dem System-internen Speicherzugriff zu tun, dass jede Zeile mit einem "glatten" Pointer-Wert anfängt.
    Bei 24bpp liegt der blanke RGB-Wert im Speicher (oder BGR).
    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!

    Haudruferzappeltnoch schrieb:

    Mit 32bpp funktioniert es.
    das sind 32 Bit = 4 Byte, das ist genau das Ausrichtungs-Kriterium.
    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!