BitmapContent.Pokeline fehlerhaft?

  • Ich habe mir eine Prozedur gebastelt, die u.a. mittels BitmapContent.Pokeline den Inhalt einer BitmapContent in eine .BMP-Datei schreibt, da ich eine solche Funktion sonst nirgends gefunden habe. Nun mein Problem:

    Alles funktioniert prima, solange im BitmapContent nicht Farben über Farbcode 127 vorkommen. Dann gibt mir Pokeline falsche Werte im Bereich der zu 'hohen' Pixel aus. Ich habe einmal ein Testbild mit angehangen, welches die Problematik gut wiedergibt.
    Die falschen Werte sind übrigens immer &HFF und &H7F

    Das paradoxe daran: In der View, welche das BitmapContent darstellt, ist die Grafik ohne Makel - Alle Farben werden korrekt dargestellt.
    Bilder, die nur Farben unter 128 verwenden werden ebenfalls korrekt dargestellt.

    Ist das eventuell ein Fehler in PokeLine?

    Mario

  • Hallo Mario,

    es gibt eine Funktion um BMP's zu schreiben: WriteBitmapToFile. Erwatet wird ein Handle, das du mit MyBitMapContent.GetBitmapHandle erhalten kannst. Für den Rest verweise ich dich mal aufs Handbuch. Menü Hilfe->Handbücher durchsuchen.Den Code (wow! sauber!) sehe ich mir jezt aber nicht im Detail an, um den Fehler zu finden (wir haben morgen schriftliche Physikprüfungen). Ich tippe aber auf das Deek(). Deek() lieste einen Integerwert, da ist &hFFFF = -1. Dein Fehler kingt so, als gäbe es damit ein Problem. PeekLine verwendet intern memcpy(), damit sollte es kein Problem geben. Kannst ja mal testweise auf Peek() umstellen.

    Gruß
    Rainer

    P.S. PokeLine und Peek/Deek sind sehr langsam.
    P.P.S PokeLine hängt keine Nullen an, aber unbenutze Speicherbereiche werden immer mit Nullen initialisiert.
    P.P.P.S Oder so: AnyStruct ist ein Array of byte. Du könntest statt der Deek-Schleife auch versuchen, eine AnyStruct Variable mit PeekS zu lesen und dann mit FileWrite so viele Bytes wie nötig zu schreiben.

    Es gibt 10 Arten von Menschen - die einen wissen was binär ist, die anderen nicht.

  • Hallo Rainer,

    es gibt eine Funktion um BMP's zu schreiben: WriteBitmapToFile. ...

    Ich hatte es geahnt, dass es sowas bereits gibt. Hatte anfangs auch im CodeWizzard danach suchen lassen - Höchstwahrscheinlich aber mit den falschen Stichworten ;(

    Ich tippe aber auf das Deek()...

    Genau da lag der Fehler. Statt 2x Deek habe ich probeweise 4x Peek verwendet und siehe da: es funktioniert!

    Letztendlich habe ich mich aber für WriteBitmapToFile entschieden, da 0.2s gegenüber 10s für eine 400x300-Grafik eindeutig für die interne Funktion sprechen. Aber zumindest konnte ich mal wieder meine Kenntnisse um das BMP-Format erweitern. Und mal schnell eigene Lösungen finden macht doch auch irgendwie Spaß. :thumbup:

    Ein großes Danke für die superschnelle Hilfe!

    Mario

  • Hallo Mario,
    gerne doch. Trotzdem bin ich für alle Feedbacks dankbar. Irgendwelche Bugs kann man nie ausschließen. Ein paar Leute wissen jetzt, was ich meine :)
    Gruß
    Rainer

    Es gibt 10 Arten von Menschen - die einen wissen was binär ist, die anderen nicht.

  • Hallo Rainer,

    Eine Frage zu o.g. Code hätte ich noch:

    Die Struktur BMPheader beginnt ja normalerweise mit dem String(2) 'Ident', welcher den Inhalt 'BM' hat- dieser wird aber nach dem Schreiben mittels FIleWrite mit einem nachfolgenden Null-Byte ausgegeben, was dazu führt, dass die Datei nicht als Bitmap erkannt wird, bzw. die Größen-Information dadurch dann an der falschen Position steht.

    Ich habe mir dann mit dem Integer 'Magic' beholfen, welcher 'BM' als Integerwert enthält und habe den String 'Ident' derweil auskommentiert. (siehe auch Code)

    Kannst du dir dieses Verhalten mit 'dem Null anhängen' erklären und wie kann man das unterbinden?

    Ansonsten finde ich R-Basic richtig klasse und arbeite sehr gern damit. Gerade die Unterstützungfunktionen (Wizzard, Beispiele, Handbuch) haben mir den Einstieg echt leicht gemacht. [size=10] [/size]:thumbup:[size=10] [/size]

    Viele Grüße,
    Mario

  • Hallo Mario,

    Ich weiß nicht, ob die Null nach dem "BM" wirklich "illegal" ist. Denn auf das "BM" folgen vier Bytes mit der "Dateigröße in Bytes", die aber üblicherweise als "unreliable" eingestuft sind:
    http://www.fastgraph.com/help/bmp_header_format.html
    https://docs.fileformat.com/image/bmp/
    Wenn sich die Null dort aber zusätzlich eingeschmuggelt hat, dann wäre das wirklich ein Fehler...

    Jörg

    There are two rules in life:
    1. Never give out all of the information.

  • Hallo Mario,
    die Null ist kein Fehler - zumindest nicht aus der Sicht von FileWrite. Wenn du einen String schreibts gehört die anschließende Null immer dazu. Deswegen belegt eine Variable vom Typ String(10) auch 11 Byte. Das wird vom Prinzip her auch bei allen Programmiersprachen so gemacht. Wenn du in C einen String char[5] definierst hast du maximal 4 Zeichen - plus die obligatorische Ende-Null.
    Das 'BM' kommt letztlich daher, dass man eine Markierung brauchte, die eine gültige BMP-Datei identifitiert. Da hat man sich für zwei Byte entschieden, die irgend einen willkürlich (!) festgelegten Wert enthalten. Aus naheliegenden Gründen hat man sich für die ASCII-Codes der Buchstaben B und M entschieden. Exe-Dateien fangen ja auch mit MZ an (nach ihrem Erfinder Mark Zbikowski).

    Dein "Work-Around" mit dem magic word ist also keine Krücke, sondern Konzept-konform. Die Definition String(2) belegt in R-BASIC 3 Byte - womit dein Header Schrott wäre (siehe auch dein Screnshot).
    Gruß
    Rainer

    P.S. Dass ein String (n) n+1 Byte belegt ist eine Konzeptenscheidung. Für den Anfänger ist es schwer zu verstehen, dass ein String(10) nur 9 Zeichen lang sein dürfte. Profis müssen dann eben damit leben :)

    Es gibt 10 Arten von Menschen - die einen wissen was binär ist, die anderen nicht.

  • Hallo Rainer,

    Mein Trugschluss, dass dies hätte funktionieren müssen kommt dann denke ich von einer Eigenheit von QBasic. Die Vorlage zum obigen Code stammt von hier . Der QBasic PUT-Befehl gibt den String*2 anscheinend nicht nullterminiert aus. Ich habe das jetzt nicht getestet, glaube aber, dass die Code-Vorlage im Link einmal funktioniert haben muss.

    Bei der nächsten Portierung weiß jetzt Bescheid. Danke dir für deine ausführliche Erklärung. :thumbup:

    Viele Grüße,
    Mario

  • Mario,
    ich gehe mal davon aus, dass du R-BASIC von meiner Webseite hast. Seit dieser Version hat sich einiges getan, auch wenn es keine "offizielle" neue Version gab. Das betrifft sowohl den Editor, z.B. verbesserte Syntax-Hervorhebung, als auch internes (Bugfixes aber auch konzeptionelle Sachen).

    Wenn du mir eine Mail schreibst, schicke ich dir die aktuelle "inoffizielle Release" zu. Wenn du willst, nehme ich dich auch in die Lister der "Tester" auf, die mit inoffiziellen Releases versorgt werden.

    Das gilt übrigens für jeden, der das liest -)
    GrußRainer

    Es gibt 10 Arten von Menschen - die einen wissen was binär ist, die anderen nicht.