ppm Datei einlesen und schreiben



  • Hallo,

    ich verzweifel gerade an dem folgenden Problem ich möchte eine *.ppm in einem C++ Programm einlesen und danach wieder abspeichern das funktioniert zwar auch aber leider kann die geschriebene Datei nicht geöffnet werden. Mittlerweile gehe ich davon aus das ich beim auslesen etwas falsch mache. In der neu gespeicherten Datei sieht soweit ich das beurteilen kann alles gleich aus aber es fehlen die Zeilenumbrüche aus der Quelldatei. Hat jemand eine Idee wo der Fehler liegen könnte ?

    Hier der Code vom einlesen

    void Picture::readBinärFile(std::string filename, int printYesNo){
    
    	//---------------------------------------------------------------------------------------------
    	// Einlesen der Header Datei
    	//---------------------------------------------------------------------------------------------
    
    	std::fstream datei;	// erzeugt einen File Stream
    
    	datei.open(filename.c_str(), std::ios::in | std::ios::binary); // Öffnet die Datei mit dem in der Main angegebenden Dateinamen
    
    	getline(datei, bildtyp); // gibt die erste Zeile der Datei und speichert sie in die Variable bildtyp
    
    	if (printYesNo == 1) {
    	std::cout << "Bildtyp:" << bildtyp << std::endl << std::endl; // Gibt den Bildtyp aus !
    	}
    
    	//---------------------------------------------------------------------------------------------
    	// Breite / Höhe / Max Farbwert - einlesen
    	//---------------------------------------------------------------------------------------------
    	std::string s;
    
    	for (int i = 0; i < 4; i++) {
    
    			if (i = 1) {
    				getline(datei, s, ' ');
    				width = atoi(s.c_str());
    				if (printYesNo == 1) {
    					std::cout << "Breite:" << width << std::endl << std::endl;
    				}
    			}
    
    			if (i = 2) {
    				getline(datei, s);
    				height = atoi(s.c_str());
    				if (printYesNo == 1) {
    					std::cout << "Hoehe:" << height << std::endl << std::endl;
    				}
    			}
    
    			if (i = 3) {
    				getline(datei, s);
    				maxColorValue = atoi(s.c_str());
    				if (printYesNo == 1) {
    					std::cout << "Maximaler Farbwert:" << maxColorValue << std::endl << std::endl;
    				}
    			}
    	}
    
    	//---------------------------------------------------------------------------------------------
    	// Einlesen der einzelnen Chars
    	//---------------------------------------------------------------------------------------------
    
    	unsigned char c;
    	/*
    	datei.read(c, sizeof(unsigned char));
    
    	*/
    
    	while (!datei.eof())
    	{
    		datei >> c;
    		picture.push_back(c);
    	}
    
    	/*
    	for (int i = 0; i < ((width*height)*3); i++)
    	{
    
    		datei >> c;
    		picture.push_back(c);
    
    	}
    	*/
    
    	datei.close(); // schließt die Datei wieder !
    
    	std::cout << "Picturesize:" << picture.size() << std::endl << std::endl;
    
    }
    

    Und hier der Code der Ausgabe

    // Schreibt das Bild als Binärdatei
    void Picture::writeBinarieFile(std::string filename){
    
    	//---------------------------------------------------------------------------------------------
    	// Schreiben der Binär Datei
    	//---------------------------------------------------------------------------------------------
    
    	std::ofstream datei;	// erzeugt einen File Stream
    	datei.open(filename.c_str(), std::ios::out | std::ios::binary); // Erstellt oder öffnet eine Binär Datei
    
    	//---------------------------------------------------------------------------------------------
    	// Schreiben des Headers
    	//---------------------------------------------------------------------------------------------
    	datei << bildtyp;
    	datei << '\n';
    	datei << width;
    	datei << ' ';
    	datei << height;
    	datei << '\n';
    	datei << maxColorValue;
    	datei << '\n';
    
    	//---------------------------------------------------------------------------------------------
    	// Schreiben der Chars
    	//---------------------------------------------------------------------------------------------
    
    	for (int i = 0; i < (picture.size()); ++i) {
    
    		datei << picture[i];
    
    	}
    
    	datei.close();
    
    }
    

    Wäre super wenn mir jemand einen Ansatz geben könnte wo das Problem liegt 😉



  • Hast du ein Binaer File oder ein Text file, dass du einlesen willst?

    Sprich wenn du dein *.ppm file mit e.g. notepad++ oeffnest stehen da Textzeilen?

    Standardmaessig funktionieren Operatoren wie "<<" ">>" nur fuer formatierten Text und nicht fuer Binaer files.

    Das bedeutet, selbst wenn du ios::binary in den header schreibst wird das ignoriert und er schreibt Text in das File.



  • Ruvi schrieb:

    Hast du ein Binaer File oder ein Text file, dass du einlesen willst?

    Sprich wenn du dein *.ppm file mit e.g. notepad++ oeffnest stehen da Textzeilen?

    Ich versuche ppm P6 auszulesen also müsste eigentlich alles bis auf den Header binär sein. Den Header leist er auch ohne Probleme aus nur später scheint es Probleme zu geben 😞 .



  • Vielen Dank habe es jetzt mit

    datei.read(reinterpret_cast<char*>(&c), sizeof(c));
    
    datei.write(reinterpret_cast<char*>(&picture[i]), sizeof(picture[i]));
    

    hinbekommen 😉


  • Mod

    Ruvi schrieb:

    Standardmaessig funktionieren Operatoren wie "<<" ">>" nur fuer formatierten Text und nicht fuer Binaer files.

    Prinzipiell funktionieren tun die schon, sowohl für das Lesen als auch das Schreiben. Sie führen aber eine Sonderbehandlung für Whitespace ein, die man normalerweise nicht möchte, wenn es darauf ankommt, dass jedes Zeichen ganz genau so wie es in der Datei steht gelesen werden soll (und umgekehrt beim Schreiben).

    (Und umgekehrt kann man natürlich auch read & Co. auf Textdaten loslassen, wobei dies oft auch nicht ist, was man möchte, da sie sämtliche Formatierungen ignorieren)



  • So wie es aussieht war genau das datei.read() mein Problem habe es jetzt mit get implementiert nun funktioniert alles so wie es soll Viele Dank nochmal


  • Mod

    pluspluscoder schrieb:

    Ich glaube ich habe jetzt genau mit dem whitespace so meine Probleme. Ich muss nach dem Lesen der Daten alle Daten durch eine Entropiekodierung jagen. Wie kann ich denn vermeiden das er beim Lesen der Daten den berücksichtigt ?

    Indem du unformatierte Lesefunktionen benutzt, wie read oder get (und nicht jeden Buchstaben einzeln! Lies doch alles in einem Block). Oder als Iterator mittels eines istreambuf_iterators.

    edit: Ich habe jetzt mal gelesen "Wie kann ich denn erreichen das er beim Lesen der Daten den berücksichtigt?" anstatt dem, was du wirklich gefragt hast, da die Frage für mich keinen Sinn machte.


Log in to reply