BMP-Bilder einlesen



  • Danke erst einmal für die tipps. ich habe nun mal genauer nachgelesen und gemerkt, dass 4 bytes die breite speichern:

    if (dst==19)
                breite=int(currByte);// was ist mit Byte 20,21,22 ?
            else if (dst==23)
                hoehe=int(currByte);
    

    der kommentar hat sich damit auch erübrigt, da auch diese für die breite verwendet werden. ich muss also nicht nur eins, sondern 4 bytes für höe bzw. breite auslesen. mir ist nun aber schleirhaft, wie ich das realisieren soll, zumal ich ja mit meinen mitteln die bytes einzeln auslesen kann. ich stehe nun der sache mit den 4 bytes auszulesen ratlos gegenüber. 😕
    könntet ihr mir da auch nochmal helfen, wie man das macht?



  • Auf 32bit Plattformen ist int 4 bytes groß, du könntest es also in
    einen int einlesen, welches aber dann wieder unschön ist.
    Im Bitmap header den du gepostet hast, war es als unsigned long deklariert,
    evtl. solltest du es dann auch als unsigned long einlesen.
    Für das einlesen mehrerer Bytes musst du dir mal die funktion read von
    ostream angucken, damit kannst du daten in ein char* array einlesen.
    Schau dir evtl. mal die FAQ an, da steht mehr über Ströme und Dateien.

    Devil



  • alles klar, ich werde ma schauen. danke nochmals
    vielleicht melde ich mich ja mal wieder 🙂 ...



  • ich habe mal versucht auf dem wege des char* array einzulesen. leider gottes komme ich auf keine grünen zweig. ich scheitere einfach diese 4 byte auszulesen, um die richtige hoehe zu bekommen 😞
    bei einem 300x300 pixel bild enthält dann das "unsigned char currByteS[4]" die werte 195 - 14 - 0 - 0, wenn ich sie in integer konvertiere.
    könnte mir bitte jemand vielleicht nochmal genau sagen, wie ich aus den 4 bytes die höhe mache, oder wie ich die hoehe genau auslese?



  • Mußt es halt noch zurechtshiften. Unter DOS/Windows wird das niederstwertige Byte zuerst gespeichert. Müßte also 0-0-14-195 sein, dann kannst's in ein int umrechnen.

    P.S.: Oder war's Intel-spezifisch? Weiß nicht mehr...



  • devil81 schrieb:

    Auf 32bit Plattformen ist int 4 bytes groß, du könntest es also in
    einen int einlesen, welches aber dann wieder unschön ist.
    Im Bitmap header den du gepostet hast, war es als unsigned long deklariert,
    evtl. solltest du es dann auch als unsigned long einlesen.

    Am besten wären hier aber typedefs, damit man es leicht für andere Plattformen anpassen kann.



  • mit dem shiften bringts aber irgendwie nix. wenn ich das char array mit 195-14-0-0 umwandle, erhalte ich für die breite 1244964. wenn ich das char array mit 0-0-14-195 umwandele erhalte ich 1244960 pixel breite.
    (wollte nur nochmal anmerken, dann die angaben 195, 14 und 0 schon mit "int(currByteS2[1])" geschrieben sind)

    hilfe ich komme hier nicht mehr weiter... 😞



  • Die Werte verstehe ich nicht.
    195-14-0-0 entspricht C3 0E 00 00 in Hex. Das sind 3 Milliarden-irgendwas. Mußt es halt so zusammenbasteln, daß da 00 00 0E C3 (= 3779 dezimal) steht. Ist das die richtige Breite deiner Bitmap?



  • nein, das bild ist 300x300 pixel groß...



  • hier mal die header:
    das ist header nr1

    struct BITMAPFILEHEADER { /* bmfh */
    UINT Type;
    DWORD Size;
    UINT Reserved1;
    UINT Reserved2;
    DWORD OffBits;
    };

    das ist header nr2(direkt unterm ersten header)

    struct BITMAPINFOHEADER { /* bmih */
    DWORD Size;
    LONG Width;
    LONG Height;
    WORD Planes;
    WORD BitCount;
    DWORD Compression;
    DWORD SizeImage;
    LONG XPelsPerMeter;
    LONG YPelsPerMeter;
    DWORD ClrUsed;
    DWORD ClrImportant;
    };

    und so kann man einen header einlesen(da das scheinbar auch ein problem war):

    ifstream a("hallo.bmp");
    BITMAPFILEHEADER header1;
    a.read(reinterpret_cast<char*>(&header1),sizeof(BITMAPFILEHEADER));
    

    alternative:

    ifstream a("hallo.bmp");
    BITMAPFILEHEADER header1;
    a>>header1.Size;
    a>>header1.Width;
    //usw
    

    achja, die header sind in der windows.h bereits enthalten^^



  • ja, das ist ja ok, nur ist mir schleierhaft, wie ich die werte dort hineinbekomme...



  • mein edit bringt klarheit 🤡



  • Dann musst du aber sicher sein, dass die struct packed ist ⚠ .



  • erstmal danke für die super hilfe von otze...
    nur nimmt er zum beispiel sieses UINT nicht an. da kommt dann immer sone fehlermeldung wie

    error C2146: Syntaxfehler : Fehlendes ';' vor Bezeichner 'Type'

    muss ich da vorher noch großartig was neues importieren oder so?

    @mastah: was meinst du denn mit packed? das kenne ich nicht...



  • Man muss einstellen, dass die Member des Struct-Objektes direkt hintereinander im Speicher liegen, also ohne padding-bytes. Das ist aber compilerspezifisch.



  • sry, doppelpost 🙄



  • alx0 schrieb:

    erstmal danke für die super hilfe von otze...
    nur nimmt er zum beispiel sieses UINT nicht an. da kommt dann immer sone fehlermeldung wie

    error C2146: Syntaxfehler : Fehlendes ';' vor Bezeichner 'Type'

    muss ich da vorher noch großartig was neues importieren oder so?

    das sind andere bezeichner für die standardtypen, schau mal in der windef.h da sind die typen drin(imho gibts für linux eine äquivalente liste)



  • tut mir leid, dass ich nochmal mit meinem problem nerven muss. ich zwar einen großen schritt vorangekommen, aber dennoch klappt es nicht. ich habe nun einmal mein script grundlegend geändert und sieht damit nun folgendermaßen aus:

    struct BMPheader
    	  {
    		// file info
    		char ID[2];
    		unsigned long filesize, reserved, offset;
    
    		// BMP info
    		unsigned long  infosize, width, height;
    		unsigned short planes, bitsperpixel;
    		unsigned long  compression, imagesize, xPixelPerMeter, yPixelPerMeter,colorsUsed, colorsImportant;
    	  };
    
    ifstream a("mein.bmp");
    	BMPheader header;
    
    a.read(reinterpret_cast<char*>(&header),sizeof(BMPheader));
    	cout<<header.ID<<endl<<header.filesize<<endl<<header.reserved<<endl<<header.offset<<endl;
    	cout<<header.infosize<<endl<<header.width<<endl<<header.height<<endl;
    	cout<<header.planes<<endl<<header.bitsperpixel<<endl;
    cout<<header.compression<<endl<<header.imagesize<<endl<<header.xPixelPerMeter<<endl<<header.yPixelPerMeter<<endl<<header.colorsUsed<<endl<<header.colorsImportant<<endl;
    

    irgenwie geht es trotzdem nicht.
    das erste, das ich merkwürdig finde ist, dass die ersten zwei zeichen "BMfu" ist und nicht "BM". die hoehe und breite wird dann mit 6553600 erkannt, obwohl es ein 300x300 großes bild ist.

    könnt ihr mir ein weiteres mal helfen?



  • ich bins nochmal.
    das problem hat sich nun gelöst, ich habe den fehler gefunden! nun geht es also.
    danke für eure hilfe 👍



  • Gerade nach so langem Hin und Her wäre es schön, wenn du schreibst, wie du es gelöst hast. 🙄


Anmelden zum Antworten