Bitmap selbst gemacht - Geht nicht! - Warum?



  • Ich will es mit dem Borland machen. Da gehts nicht. Wenn ichs im Visual Studio .NET versuche kriege ich auch ein grünes Bild.

    Scheint also ein Entwicklungsumgebungsabhängig zu sein! 😞

    Im Vergleich die Header der beiden Bilder:
    Header im BCB (alles zwischen den Anführungsstrichen):

    "BM 8     8   (   €   þÿÿ          ·   ·              "
    

    Header im VS.NET (alles zwischen den Anführungsstrichen):

    "BM6     6   (   €   þÿÿ          ·   ·               "
    

    Header im mit Paint erstellten Bild (alles zwischen den Anführungsstrichen):

    "BM6     6   (   €  à                          "
    

    Aber der Vergleich mit Paint zeigt noch andere Unterschiede...



  • Nachtrag zu oben:

    So ganz in Ordnung ist das Bild aus dem VS.NET auch nicht. Bei Versuch, das Bild mit nem Grafikprogramm (!= Paint) zu öffnen kommt die Meldung "Bad Picture size".



  • generier doch in paint ein bitmap und vergleiche diese dateien mit dem hexeditor.





  • Ich glaube du musst unten statt BITMAPINFO nur BITMAPINFOHEADER schreiben.



  • geeky schrieb:

    Ich glaube du musst unten statt BITMAPINFO nur BITMAPINFOHEADER schreiben.

    Hab ich schon versucht, tut sich in dem Fall aber nichts.
    Habe jetzt schon mal eine Teillösung.
    Das Problem liegt beim BCB6. Beim Byte-weisen schreiben von Strukturen hat der "Kollege" einen Bug, nämlich dass jede Struktur 2 Byte länger geschrieben wird, als sie ist. Wurde im Update 4 behandelt, hab ich aber nicht drauf. 😉 Lässt sich aber auch über einen #pragma lösen.

    Das ganze geht jetzt soweit auch im BCB. Das Problem der "Bad Picture Size"-Meldung liegt daran, dass

    bmih.biHeight        = -height;  // negative to be a top-down-image
    

    ist. Das muss negativ sein um ein top-down bild zu werden. Positiv gesetzt ist es ein bottom-up dings, was auch die verdrehten Farben erklärt (BGR statt RGB)

    Ich danke euch trotzdem allen vielmals!!!



  • Die Bitmap-Datengröße ist nicht einfach breite*höhe*bitsperpixel, da jede Scanline an 4-Byte-Grenzen ausgerichtet sein muss und der Rest der Scanline mit Nullen aufgefüllt wird. Hast du also ein 2*1*24-Bitmap müssen die Daten so aussehen:

    XXXXXXXX XXXX0000

    Besser wäre also dieser Weg, die Bitmap-Datengröße zu berechnen.

    #define BITMAP_SIZE ( (((BITMAP_WIDTH * BITMAP_BPP) + ((BITMAP_WIDTH*BITMAP_BPP)%32)) / 8) * BITMAP_HEIGHT)
    

    Die PixelsPerMeter-Werte brauchst du nur für geräteabhängige Bitmaps und stellen in dem Fall die Auflösung des Gerätes dar. Da helfen auch keine dummen Kommentare (für wen überhaupt?)

    bmiColors ist in der Standard-Structdeklaration ein RGBQUAD[1]-Array. Das wird also mit bmi.bmiColors[0] = 0; auf null gesetzt, wobei das ja eigentlich nicht erforderlich ist, da du ja kein Bild mit indizierten Farben verwendest.



  • masterofx32 schrieb:

    Die Bitmap-Datengröße ist nicht einfach breite*höhe*bitsperpixel, da jede Scanline an 4-Byte-Grenzen ausgerichtet sein muss und der Rest der Scanline mit Nullen aufgefüllt wird. Hast du also ein 2*1*24-Bitmap müssen die Daten so aussehen:

    XXXXXXXX XXXX0000

    Besser wäre also dieser Weg, die Bitmap-Datengröße zu berechnen.

    #define BITMAP_SIZE ( (((BITMAP_WIDTH * BITMAP_BPP) + ((BITMAP_WIDTH*BITMAP_BPP)%32)) / 8) * BITMAP_HEIGHT)
    

    Aha! Gut, Danke! Wusste ich nicht.

    masterofx32 schrieb:

    Die PixelsPerMeter-Werte brauchst du nur für geräteabhängige Bitmaps und stellen in dem Fall die Auflösung des Gerätes dar. Da helfen auch keine dummen Kommentare (für wen überhaupt?)

    Die dummen Kommentare helfen da sicherlich, wenn auch nicht dir. Ich kommentiere Quellcode im seltensten Fall nur fürs Forum. Die Kommentare waren also vorher schon da. Für mich!
    Dumme Kommentare entstehen in diesem Fall, da meines Wissens nach üblicherweise diese Werte in dpi, also dots per inch = pixel pro Zoll(!) und nicht pro Meter(!) angegeben werden, was nach meiner Meinung wieder eine unnötige Umrechnung birgt.
    Solltest du dich durch meine derart dummen Kommentare persönlich angegriffen fühlen, übernehme ich selbstverständlich die gesamte Verantwortung, bin zutiefst betroffen und entschuldige mich mehrfach! 😉

    masterofx32 schrieb:

    bmiColors ist in der Standard-Structdeklaration ein RGBQUAD[1]-Array.
    Das wird also mit bmi.bmiColors[0] = 0; auf null gesetzt,

    Dachte ich auch, lässt aber mein Compiler nicht zu. Auch alle anderen Versuche schlugen fehl!

    masterofx32 schrieb:

    wobei das ja eigentlich nicht erforderlich ist, da du ja kein Bild mit indizierten Farben verwendest.

    Noch. Das hier war quasi nur die Vorstufe. Ich muss mal sehen, in wie fern ich da noch weiter "rum experimentiere". 🙂

    Danke für deine Mühe.



  • bmfh.bfType = MAKEWORD('B', 'M');



  • el Clio schrieb:

    Solltest du dich durch meine derart dummen Kommentare persönlich angegriffen fühlen, übernehme ich selbstverständlich die gesamte Verantwortung, bin zutiefst betroffen und entschuldige mich mehrfach! 😉

    😉

    Mit der Angabe in Pixeln pro Meter hat man ja eine bessere "Ganzzahl-Auflösung". Denn würde man ein DDB für eine Videowand mit 100 Pixeln pro Meter erstellen, ließe sich das in DPI nur ungenau ganzzahlig ausdrücken. Außerdem ist das metrische System sowieso das bessere. 🙂

    el Clio schrieb:

    masterofx32 schrieb:

    bmiColors ist in der Standard-Structdeklaration ein RGBQUAD[1]-Array.
    Das wird also mit bmi.bmiColors[0] = 0; auf null gesetzt,

    Dachte ich auch, lässt aber mein Compiler nicht zu. Auch alle anderen Versuche schlugen fehl!

    Ach so, ich nahm an, dass RGBQUAD auch nur ein DWORD sei wie COLORREF. Habe ich mich wohl geirrt. Keine Ahnung, wie das in dem Beispielquelltext gemacht wurde. Da es dafür scheinbar kein Makro gibt, wirst du es wohl so machen müssen:

    bmi.bmiColors[0].rgbBlue = 0;
    bmi.bmiColors[0].rgbGreen = 0;
    bmi.bmiColors[0].rgbRed = 0;
    bmi.bmiColors[0].rgbReserved = 0;
    
    //oder
    
    ZeroMemory(bmi.bmiColors,sizeof(RGBQUAD));
    

Anmelden zum Antworten