Bitmap einlesen und Headerinformationen auslesen



  • Hallo NG!

    Nun habe ich etliche Foren durchsucht, auch Google gefragt, Codeguru, Codeproject und Co. auch abgegrast, doch nirgendwo finde ich einen vernünftigen Quellcode, der ein Bitmap beliebiger Größe und beliebiger Farbtiefe einliest und in ein Array speichert.

    Der bestimmt beste Code ist dieser hier:

    #include <iostream> 
    #include <fstream> 
    
    #include <cmath> 
    #include <stdlib.h> 
    #include <stdio.h> 
    #include <time.h> 
    #include <iomanip>
    #include <windows.h>
    
    using namespace std;
    
    ifstream inputFile("mein.bmp", ios::binary | ios::in);//oeffnet den lesestream
    BITMAPFILEHEADER header1;
    inputFile>>header1.Size;
    inputFile>>header1.Width;
    
    ofstream file("outgoing.bmp", ios::out|ios::binary); 
    int ***imagearray;//array der pixel: hoehe breite des pixels + 1ster,2ter,3ter farbwert desses 
    int hoehe,breite; 
    
    void sleep() 
    { 
        int t; 
        for (t=0;t<100000000;++t) 
        {}; 
    } 
    
    void printer() 
    { 
        int i,j; 
        for (i=0;i<hoehe;++i)                            //Ausgabe des Inhaltes des Arrays 
        { 
            for(j=0;j<breite;++j) 
            { 
                cout<<imagearray[i][j][0]<<" , "<<imagearray[i][j][1]<<" , "<<imagearray[i][j][2]<<endl; 
            } 
            cout<<endl; 
            sleep(); 
        } 
    }; 
    
    void einlesen()//das bild wird von links unten nach rechts oben ausgelesen 
    { 
    
        unsigned char currByte;//hat den index dst 
        int dst=1,i,j,pixel=1,h;//dst ist dateistelle 
        float tripel[3];//enthaelt die 3 farbwerte eines pixels 
    
        while (dst<55)//auselen des headers 
        { 
            currByte = inputFile.get();//ein element der datei wird in currByte geschrieben 
            cout<<int(currByte)<<endl; 
            if (dst==19) 
                breite=int(currByte); 
            else if (dst==23) 
                hoehe=int(currByte); 
            ++dst; 
            file.write( (char*) &currByte,1);//Uebertragen des Headers in die Datei 
        } 
    
        cout<<breite<<" - "<<hoehe<<endl; 
        imagearray=new int**[hoehe]; 
        for(j=0;j<hoehe;++j)//Allokieren des Array Image, das die bildpixelinformationen speichert 
        { 
           imagearray[j]=new int*[breite]; 
           for(i=0;i<breite;++i) 
             imagearray[j][i]=new int[3]; 
        } 
        h=0; 
        cout<<"Noch einzulesene Zeilen: "<<endl; 
        float *zeile;                //allokieren des array, 
        zeile= new float[breite];    //der eine zeile des bildes speichert. 
        const unsigned long 
            linesize =3*breite, 
            fillbytes = (4-linesize%4)%4; 
    
        while (dst<=breite*hoehe*3+55)//abfragen der farbwerte aller bilpunkte 
        { 
            currByte = inputFile.get();//siehe oben 
            if ((((dst-55)%(3*breite))==0)&&(dst>55)) //wenn zeile zu ende 
            { 
                for(i=0;i<breite;++i)/////// ausgabe der graustufen fuer alle pixel in einer zeile, 
                    imagearray[h][i][0]=imagearray[h][i][1]=imagearray[h][i][2]=zeile[i];//Uebertragen der Grauwerte in das Array 
                cout<<hoehe-h<<", "; 
    
                for(i=0;i<fillbytes;++i)        //herausstreichen der zusatzinformationen am ende der zeile 
                    currByte = inputFile.get(); 
    
                ++h; 
            } 
            tripel[(dst-55)%3]=int(currByte);//einlesen der farbinformation eines pixels, format: B G R 
            if ((((dst-55)+1)%3)==0) //jeden dritten eingabewert (nach b-r-g) //(dst-55) ergibt die pixelnummer, da der header(55) abgezogen wurde 
            { 
                zeile[(pixel-1)%breite]=((tripel[0]+tripel[1]+tripel[2])/3);//berechnung der graustufe, als mittelwert der farben(falls ein farbiges bild eingegeben wird), da eine graustufe bei R,G,B die selben werte hat 
                ++pixel; 
            } 
            ++dst; 
        } 
        cout<<endl<<"Fertig mit einlesen"<<endl; 
    }; 
    
    void ausgeben() 
    {    
        int i,i2; 
        unsigned char currByte; 
        const unsigned long 
            linesize =3*breite,   // 24 bit per pixel 
            fillbytes = (4-linesize%4)%4, // at line end to quad boundary 
            imagesize = (linesize+fillbytes)*hoehe; 
    
        /*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; 
          } header = 
          { // file info 
            { 'B', 'M' }, 
            sizeof(header) + imagesize, // 24 bits per pixel 
            0, sizeof(header), // 0x36 
    
            // BMP info 
            40, breite, hoehe, 
            1, 24, 
            0, imagesize, 
            1000, 1000, 
            0, 0 
          }; 
        file.write( (char*)&header, sizeof(header));*/ 
    
        cout<<"Noch auszugebene Zeilen: "<<endl; 
        for (i=0;i<hoehe;++i) 
        { 
            for(i2=0;i2<breite;++i2) 
            { 
                currByte=imagearray[i][i2][0]; 
                file.write((char*) &currByte,1); 
    
                currByte=imagearray[i][i2][1]; 
                file.write((char*) &currByte,1); 
    
                currByte=imagearray[i][i2][2]; 
                file.write((char*) &currByte,1); 
            } 
    
            if(fillbytes) 
            { 
              int zero = 0; 
              file.write( (char*) &zero, fillbytes); 
            } 
    
            cout<<hoehe-i<<", "; 
        } 
        cout<<endl<<"Fertig mit ausgeben"<<endl<<endl; 
    }; 
    
    void main () 
    { 
        einlesen(); 
        ausgeben(); 
    
    }
    

    Hier habe ich aber das Problem, dass weder der BitmapInfoHeader noch der BitmapFileHeader ausgelesen werden können. Von den Größenbeschränkung auf Bilder mit weniger als 256 Pixeln gehts ja garnicht mehr.

    Kennt jemand einen guten Quelltext oder eine gut dokumentierte LIB, mit der ich Bitmaps einlesen und in ein Array speichern kann ???



  • http://www.wotsit.org/search.asp?s=graphics
    bsp: http://www.gamedev.net/reference/articles/article1966.asp
    lib's: SDL, Devil, usw usw.

    2Atlantis schrieb:

    Der bestimmt beste Code ist dieser hier:

    mit sicherheit nicht

    2Atlantis schrieb:

    ifstream inputFile("mein.bmp", ios::binary | ios::in);//oeffnet den lesestream
    BITMAPFILEHEADER header1;
    inputFile>>header1.Size;
    inputFile>>header1.Width;
    
    ofstream file("outgoing.bmp", ios::out|ios::binary); 
    int ***imagearray;//array der pixel: hoehe breite des pixels + 1ster,2ter,3ter farbwert desses 
    int hoehe,breite; 
    }
    

    was los das hier?

    2Atlantis schrieb:

    Hier habe ich aber das Problem, dass weder der BitmapInfoHeader noch der BitmapFileHeader ausgelesen werden können. Von den Größenbeschränkung auf Bilder mit weniger als 256 Pixeln gehts ja garnicht mehr.

    😕 warum 😕

    ps: schmeiss den code am besten weg



  • Das Beispiel werde ich gleich mal durcharbeiten.
    Was mich aber generell bei den vielen Tutorials im Netz wundert, ist, dass die meisten anfangen, den struct von dem BitmapInfoHeader und dem BitmapFileHeader neu aufzustellen. In der windows.h ist diese Struktur schon drin und braucht eigentlich nicht neu definiert zu werden.

    Mein BITMAPINFOHEADER und BITMAPFILEHEADER sollte eigentlich aus dem eingelesenen Bitmap den Header auslesen. Aber wahrscheinlich funktioniert die Kommunikation irgendwie nicht.

    Ich meld mich, wenn ich das Beispiel durchgearbeitet habe!



  • Hallo miller_m!

    Auf der Seite, die Du mir vorgeschlagen hast, ist eine wirklich gute Dokumentation, aber wenn ich den Code ausführen will, erhalte ich immer wieder diese Fehlermeldung:

    BMPReading error LNK2019: unresolved external symbol _main referenced in function _mainCRTStartup
    

    Ich denke, dass damit auch die zweite Fehlermeldung zusammenhängt:

    BMPReading fatal error LNK1120: 1 unresolved externals
    

    Nachdem ich in diversen Foren und bei MSDN geschaut hab, werden alle Forumschreiber sprachlos, wenn es um die erste Fehlermeldung geht. *grummel



  • 2Atlantis schrieb:

    Das Beispiel werde ich gleich mal durcharbeiten.
    Was mich aber generell bei den vielen Tutorials im Netz wundert, ist, dass die meisten anfangen, den struct von dem BitmapInfoHeader und dem BitmapFileHeader neu aufzustellen. In der windows.h ist diese Struktur schon drin und braucht eigentlich nicht neu definiert zu werden.

    schon klar, wird meistens wegen der plattformunabhängigkeit gemacht

    2Atlantis schrieb:

    Auf der Seite, die Du mir vorgeschlagen hast, ist eine wirklich gute Dokumentation, aber wenn ich den Code ausführen will, erhalte ich immer wieder diese Fehlermeldung:

    liegt nicht an dem code sondern an deinen projekteinstellungen
    http://msdn.microsoft.com/library/deu/default.asp?url=/library/DEU/vccore/html/_core_.2f.entry.asp



  • okay, hab mir eine main geschrieben, jetzt gehts


Anmelden zum Antworten