Ich fang mit binär Dateien an!



  • Geht auch, struct hat aber default-access public, class aber private 😛 Und bei solchen Arbeiten ist es d.h. dann ratsam mit struct zu arbeiten 😉



  • Mh, wenn wir schon dabei sind, dann können wir gleich bei mir eine Wissenlücke schließen. Wie is n das genau gemeint, das bei "struct" alles public ist? Also irgendwie weiß ich nicht recht was der Unterschied zwischen eienr Klasse und einem struct ist. Weil ein struct kann ich doch auch mit dem Schlüsselwort "pirvate" pirvat machen? Und einen Konstruktor\Destruktor hat es ja auch, einziger Unterschied ist doch das man es nicht vererben kann? Oder etwa doch?
    Und Klassen kann ich doch auch ganz "public" lassen..... Was ist den jetzt der unterschied zwischen "struct" und "class". Sry für die dumme Frage 🙂
    MfG
    Stromberg



  • struct und class sind von den Möglichkeiten, die du hast identisch. Du kannst also auch von einem Struct erben, usw.
    Der einzige Unterschied ist, dass struct als Standard-Zugriffsrecht public und class private hat. Das merkst du sowohl beim Memberzufgriff als auch bei der Vererbung (struct wird ohne spezielle Angabe public, und class privat vererbt).
    Natürlich kann man das, wie du bereits erkannt hast, auch alles explizit angeben und nur eins von beidem nutzen.

    Gruß
    Don06



  • struct Foo 
    {
        int f; 
    };
    // ==
    class Bar 
    { 
        public: int b; 
    };
    
    // entsprechend
    
    struct Foo 
    { 
        private: int f; 
    };
    // ==
    class Bar 
    { 
        int b; 
    };
    

    Einen anderen Unterschied als den zwischen Default-Public und Default-Private gibt es nicht.



  • struct und class sind in C++ gleich, der einzige Unterschied ist die Default-Sichtbarkeit der Member:

    //Hier ist bar public
    struct foo
    {
       int bar;
    }
    
    //...aber hier private
    class foo
    {
      int bar;
    };
    

    Ansonsten sind beide gleich, du kannst für beide die jeweiligen Sichtbarkeitsattribute festlegen, Konstruk/Destruktoren definieren und auch von beiden ableiten...

    Grüße

    Martin



  • "struct" kommt doch aus C oder? Und wenn ihr sagt, das man auch mit struct Vererben kann, dann gabs Vererbung ja auch schon in C oder? Und Vererbung ist doch ein wesentlicher Teil einer OO-Sprache oder?

    Wenn zwischen struct und class eigentlich kein "Unterschied" ist, außer das mit dem default, welches von beiden ist den schneller? Weiß man da was?

    MfG
    Stromberg



  • sind identisch (=> performance identisch) ...
    Unter C waren struct nen bissel anders ...

    typedef struct tagDATA
    { 
        int data;
    } DATA;
    

    ...



  • Okay, zurück zu BMP Dateien. Ich lese da einfach die einzelnen Byte nacheinander in die binär Datei ein wies vom Standard verlangt wird. Oder muss ich da auf irgendwas besonderes achten? Das 4te Argument vom Dateikopf heißt: "Offset der Bilddaten in Byte vom Beginn der Datei an"...was genau heißt das für normal sterbliche? Was muss ich da angeben? Das 2te Argument ist die gesamt größe der BMP-Datei in Byte, doch wie kann ich diese am Schluss berechnen?
    Das 1ste Argument ist: "ASCII-Zeichenkette "BM" (Dezimalwert 19778).", da gebe ich halt einfach die "19778" ein, aber für was steht das genau bzw. es steht ja für "BM", aber was für ein Rechensystem...ist das?
    Ich hoff mal es gibt hier einen BMP Datei Experte hier 😃
    MfG
    Stromberg



  • Offset der Bilddaten in Byte vom Beginn der Datei an

    Hmm wie viele Bytes du von std::ios_base::beg nach vorne seekg'en musst, bis du bei den Daten der Bitmap (Pixeln) ankommst.

    BM

    Hmm ist eine Methode um Dateien eindeutig als ein Typ zu identifizieren (Bitmap) ...

    Das 2te Argument ist die gesamt größe der BMP-Datei in Byte, doch wie kann ich diese am Schluss berechnen?

    ... man nimmt nicht die dort angegebene Zahl ... man nimt sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER) + bm.nWidth * bm.nHeight, soweit ich mich erinnern kann ...

    http://www.vbforums.com/archive/index.php/t-261522.html sollte dir vllt helfen ...



  • Eieiei, das hätt ich mir irgendwie alles einfach vorgestellt, ich glaub füher oder später werd ich des Projekt einstellen, weil ichs net schaffen werde. Aber "soweit" bin ich schon mal, hättet ihr auch so eine Struktur gemacht?
    Nur mit den "Bilddaten" (ImageFiles) hab ich noch gar keinen Plan wie ich das machen will, also bis jetzt nur einen Zeiger, mit dem ich später Speicher für ein Array reservieren möchte. Kann mir bei diesem Punkt noch jemand helfen? Also wer sowas schon mal gemacht hat, wäre net wenn er mir paar Gedankenanstösse, Tipps.... geben würde. 🙂

    #include <iostream>
    #include <fstream>
    using namespace std;
    
    class BMP
    {
        public:
    
        private:
    
        struct Header
        {
            short m_kennung;
            int m_groesse;
            int m_reserved; //immer 0
            int m_offset;
        };
        struct Attributs
        {
            int m_groesseBlock;
            int m_breite;
            unsigned int m_hoehe; //darf in meiner Version nur poitiv sein
            short m_planes; //immer 0
            short m_farbtiefe;
            int m_kompression;
            int m_groesseBilddaten;
            int m_horizontal;
            int m_vertikal;
            int m_farbtabelle;
            int m_alleFarben;
        };
        struct ImageFiles
        {
            int *m_pixels;  
        };
    
    };   
    
    int main()
    {
    
        return 0;
    }
    

    MfG
    Stromberg



  • die Strukturen müssen so aussehen:

    #include <fstream>
    
    class Bitmap : public File
    {
    	struct FileHeader
    	{
    		unsigned short type;
    		unsigned long size;
    		unsigned long reserved;
    		unsigned long offset;
    		FileHeader() 
    			: type(0), size(0), reserved(0), offset(0)
    		{}
    	} m_fileheader;
    
        struct InfoHeader
        {
    		enum Compression {
    			RGB = 0, 
    			RLE8, 
    			RLE4,
    			BITFIELDS
    		};
    		unsigned long size;
    		unsigned long width;
    		unsigned long height; // width * height == Anzahl der Pixel!
    		unsigned short planes;
    		unsigned short bit_count;
    		unsigned long compression;
    		unsigned long size_data;
    		unsigned long x_ppm;
    		unsigned long y_ppm;
    		unsigned long colors_used;
    		unsigned long colors_important;
    		InfoHeader()
    			: size(0), width(0), height(0) planes(1), bit_count(24), compression(RGB), size_data(0), 
    			x_ppm(0), y_ppm(0), colors_used(0), colors_important(0)
    		{}
        } m_infoheader;
    
    public:
    	Bitmap(const char* file_name) { load_file(file_name); }
    	Bitmap() {}
    
    public:
    	void load_file(const char* file_name) 
    	{
    		std::ifstream file_stream(file_name, std::ios::binary);
    		if (!file_stream) throw std::invalid_argument("invalid file");
    		file_stream.read(reinterpret_cast<char*>(&m_fileheader), sizeof(FileHeader));
    		file_stream.read(reinterpret_cast<char*>(&m_infoheader), sizeof(InfoHeader));
    	}
    };
    

    ... dann guck nur das du das padding für die Strukturen ausstellst ... kann sonst schief gehen 😉



  • Meine Fragen:
    1.
    Mit wemm ist Bitmap da verwandt

    class Bitmap : public File
    

    ? Wer ist File bzw. was ist File?
    2. Wenn bei struct nacher der letzten geschweiften Klammer "}" noch n Name kommt, wie hier z.B. "m_fileheader" ist das dann einfach ein Objekt von dem struct? Also wie wenn ich z.B. "FileHeader m_fileheader" schreibe?

    MfG
    Stromberg



  • 1. Noch ist es keine Klasse ... es wäre aber z.B. möglich, dass du dir eine Klasse File anlegst die du abstract machst. Dann machst du z.B. auch für JPEG und PNG usw. eine Klasse die davon erbt usw. Also muss aber nicht, kannst auch einfach ": public File" weglassen 😉
    2. Ja, richtig erkannt 😉



  • So sieht das ganze dann am stück aus, aber die Funktion "load_file" habe ich bissel verändert, ich hab des net ganz verstanden, du wolltest da nur ein "file" zum lesen öffnen, ich wollte doch eine ganz neue .BMP Datei erstellen.

    #include <fstream>
    #include <iostream>
    
    class Bitmap
    {
        struct FileHeader
        {
            unsigned short type;
            unsigned long size;
            unsigned long reserved;
            unsigned long offset;
            FileHeader()
                : type(0), size(0), reserved(0), offset(0)
            {}
        } m_fileheader;
    
        struct InfoHeader
        {
            enum Compression {
                RGB = 0,
                RLE8,
                RLE4,
                BITFIELDS
            };
            unsigned long size;
            unsigned long width;
            unsigned long height; // width * height == Anzahl der Pixel!
            unsigned short planes;
            unsigned short bit_count;
            unsigned long compression;
            unsigned long size_data;
            unsigned long x_ppm;
            unsigned long y_ppm;
            unsigned long colors_used;
            unsigned long colors_important;
            InfoHeader()
                : size(0), width(0), height(0), planes(1), bit_count(24), compression(RGB), size_data(0),
                x_ppm(0), y_ppm(0), colors_used(0), colors_important(0)
            {}
        } m_infoheader;
    
    public:
        Bitmap(const char* file_name) { load_file(file_name); }
        Bitmap() {}
    
    public:
        void load_file(const char* file_name)
        {
            std::ofstream file_stream(file_name, std::ios::out | std::ios::binary);
            //if (!file_stream) throw std::invalid_argument("invalid file");
            file_stream.write(reinterpret_cast<char*>(&m_fileheader), sizeof(FileHeader));
            file_stream.write(reinterpret_cast<char*>(&m_infoheader), sizeof(InfoHeader));
        }
    };
    
    int main()
    {
        class Bitmap test;
        test.load_file("D:/bild.bmp");
    
        return 0;
    }
    

    Zumindestens gibts jetzt in "D:\" tatsächlich eine BMP Datei namens "bild.bmp". Mit Paint konnte ich sie nicht öffnen, da kam eine Fehlermeldung, dass das Format nicht erkannt werden konnte. Warum nicht?
    Zumindestens konnte ich sie mit so nem Nero Bildprogramm öffnen, des heißt "Nero PhotoSnap Viewer". Warum gehts mit dem, aber nicht mit Paint?
    Hier ist das Ergebnis vom Bild: http://www.pictureupload.de/originals/pictures/231207125824_Unbannt.bmp
    Is aber noch um einiges Verbesserungswillig. Was bei dem Code doch überhaupt fehlt, ist doch der 3te Teil einer BMP-Datei, die Bilddaten oder? Hört sich in Wikipedai aber wieder schrecklich kompliziert an....
    Na ja, ich warte jetzt erst mal auf deine Meinung.
    MfG
    Stromberg



  • hmm ... naja ich hatte in load_file jetzt auch eine Bitmap laden wollen 😛

    Naja guck mal ob sizeof(FileHeader) == 14 ist und sizeof(InfoHeader) == 40. Wenn nicht, musst du padding abstellen.

    Wenn der Header schonmal stimmt, gehst du jetzt hin und füllst die Daten ... müsste eigtl BGR Ausrichtung sein ...

    #include <cstdlib> // std::srand, std::rand
    #include <ctime> // std::time
    
    std::srand(static_cast<unsigned>(std::time(NULL)));
    
    for (unsigned long x(0); x < bm.width; ++x)
        for (unsigned long y(0); y < bm.height; ++y)
        {
            unsigned char color[3] = { std::rand() % 256, std::rand() % 256, std::rand() % 256 };
            file_stream.write(reinterpret_cast<const char*>(&color), sizeof(unsigned char) * 3);
        }
    

    sollte dir dann alles mit Zufallswerten füllen 😉



  • Äh was is padding? Irgend eine Compiler Option?
    MfG
    Stromberg



  • Stromberg schrieb:

    Äh was is padding? Irgend eine Compiler Option?
    MfG
    Stromberg

    Lies mal diesen Thread durch, da gings auch um Padding 🙂



  • Folgendes, sizeof(m_fileheader) war 16 und sizeof(m_infoheader) war 40. Somit habe ich bei "struct FileHeader" das padding ausgeschalten. Hat auch super geklappt, und sizeof(m_fileheader) war 14. Nur kann ich jetzt die Datei auch nicht mal mehr mit dem "Nero PhotoSnap Viewer" öffnen, und mit Paint wie schon gehabt auch net.
    Hier der Code:

    #include <fstream>
    #include <iostream>
    
    class Bitmap
    {
        public:
        #pragma pack (1)
        struct FileHeader
        {
            unsigned short type;
            unsigned long size;
            unsigned long reserved;
            unsigned long offset;
            FileHeader()
                : type(0), size(0), reserved(0), offset(0)
            {}
        } m_fileheader;
        #pragma pack (pop)
    
        struct InfoHeader
        {
            enum Compression {
                RGB = 0,
                RLE8,
                RLE4,
                BITFIELDS
            };
            unsigned long size;
            unsigned long width;
            unsigned long height; // width * height == Anzahl der Pixel!
            unsigned short planes;
            unsigned short bit_count;
            unsigned long compression;
            unsigned long size_data;
            unsigned long x_ppm;
            unsigned long y_ppm;
            unsigned long colors_used;
            unsigned long colors_important;
            InfoHeader()
                : size(0), width(0), height(0), planes(1), bit_count(24), compression(RGB), size_data(0),
                x_ppm(0), y_ppm(0), colors_used(0), colors_important(0)
            {}
        } m_infoheader;
    
    public:
        Bitmap(const char* file_name) { load_file(file_name); }
        Bitmap() {}
    
    public:
        void load_file(const char* file_name)
        {
            std::ofstream file_stream(file_name, std::ios::out | std::ios::binary);
            //if (!file_stream) throw std::invalid_argument("invalid file");
            file_stream.write(reinterpret_cast<char*>(&m_fileheader), sizeof(FileHeader));
            file_stream.write(reinterpret_cast<char*>(&m_infoheader), sizeof(InfoHeader));
        }
    };
    
    int main()
    {
        class Bitmap test;
        std::cout << sizeof(test.m_fileheader) << std::endl;
        std::cout << sizeof(test.m_infoheader) << std::endl;
        test.load_file("D:/bild.bmp");
    
        return 0;
    }
    

    MfG
    Stromberg



  • Ich hab vor vielen Jahren mal so eine Klasse geschrieben, nachdem ich herausgefunden hatte, wie man Binärdateien schreibt. Von Dateiformatspezifikationen hatte ich da mangels frei zugänglichem Internet noch keine Ahnung, hab mir das Ganze aus bereits vorhandenen Bitmapdateien erschlossen... die Klasse produziert aber Bitmaps, die man auch in anderen Programmen laden kann (aber die Praxis, für jeden einzelnen Pixel write() aufzurufen, sollte man evtl. nicht nachahmen).
    Also, falls es helfen sollte:

    http://91.34.101.164/TFastBitmap.cpp



  • Warum beschreibst du eigentlich die Datei bei "load_file"?

    Naja, jedenfalls können Bildbearbeitungsprogramme dein Bild wohl nicht öffnen, weil noch nicht einmal der Typ am Anfang stimmt. Du solltest schon gültige Werte in den Strukturen setzen, sonst klappt das nie 😉


Anmelden zum Antworten