Hex zu JPEG. Wie?



  • Hallo zusammen,

    wie schon oben gennant, möchte ich gerne aus Hex ein Bild machen.
    Also ich habe mit meinem Pogramm/Code:

    #include <fstream>
    
    using namespace std;
    
    int main()
    {
       ifstream In;
       ofstream Out;
       char ch;
    
       In.open( "bild.jpg", ios::binary );
       Out.open( "Output.txt", ios::app );
    
      while( In.get(ch) )
        Out << hex << (((int)ch) & 0xFF);	
    }
    

    Eine Output.txt Datei erstellt. In dieser sind Hex Zahlen bzw. Buchstaben drin.
    Jetzt möchte ich aus der Datei Output.txt wieder ein bild.jpg bekommen.

    Wie mache ich das???

    In Wikipedia habe ich mir schon den Bericht über Jpeg auf Deutsch und Englisch angeguckt. Verstanden habe ich schon was da drin steht. Aber wirklich anfangen kann ich damit nix. In dem Artikel stand irgendwas zum Dekodieren indem man
    0x00 verwendet statt 0xFF. Dann stehen aber in der Jpeg Datei nur Nullen.

    Hat irgendjemand eine Idee?

    ////// Ich benutzte Dev-Cpp hierfür, habe aber auch Visual Cpp



  • Was willst du machen?

    Was für hex zeichen sind in dieser Datei drin?

    Willst du etwas wie folgendes machen?

    1. bild1.jpg auslesen und in text.txt speichern
    2. text.txt auslesen und in bild2 speichern.

    allgemein empfehle ich dev-cpp in den mülleimer zu schmeißen



  • Wenn du es so machst, werden Bytes mit Werten <16 nur "einstellig" in die Datei geschrieben, was das Rekonstruieren nachher unmöglich macht.
    Mit Streammanipulatoren kannst du das trotzdem hinbiegen:

    #include <fstream>
    #include <iomanip>
    using namespace std;
    
    int main()
    {  
      ifstream in;
      ofstream out;
    
      in.open("bild.jpg",ios::binary);
      out.open("output.txt",ios::trunc);
    
      out << hex << setfill('0');
      while (in.good())out << setw(2) << in.get();
    }
    

    Umgekehrt z.B. so:

    #include <fstream>
    using namespace std;
    
    static inline int hexCharToInt(char ch)
    {
      if (ch>='0' && ch<='9')return ch-'0';
      if (ch>='a' && ch<='f')return ch-'a'+10;
      if (ch>='A' && ch<='F')return ch-'A'+10;
      return 0;
    }
    
    static inline unsigned char hexPairToByte(char hi,char lo)
    {
      return (hexCharToInt(hi)<<4)|hexCharToInt(lo);
    }
    
    int main()
    {
      ifstream in;
      ofstream out;
    
      in.open("output.txt",ios::binary);
      out.open("bild2.jpg",ios::binary | ios::trunc);
    
      char ch,ch2;
      while(!in.eof() && in.get(ch) && in.get(ch2))out << hexPairToByte(ch,ch2);  
    }
    

    Edit: Ach ja, und Dev-C++ solltest du umgehend durch Code::Blocks ersetzen.



  • Cool, vielen Dank und auch für die schnellen Antworten.
    Funktioniert alles.

    Jetzt habe ich nocheinmal eine frage zu z.B.:

    static inline int hexCharToInt(char ch)
    

    Warum macht man nicht normal:

    int hexCharToInt(char ch)
    

    Wofür ist das "static inline" gut?

    Und wofür steht das:

    setw(2)
    

    Beim ersten Output?

    Vielen Dank nochmal.



  • static inline kannst du auch weglassen.
    inline weist den Compiler an, den Code der Funktion möglichst direkt an die Stelle des Funktionsaufruf einzufügen, so dass der eigentliche Aufruf komplett entfallen kann. Moderne Compiler ignorieren inline aber meist sowieso, da sie selbst (besser) entscheiden können, ob es Sinn macht, die Funktion zu inlinen oder nicht.

    static weist die Funktion als lokal aus (d.h. wenn du eine weitere Funktion namens hexCharToInt in einer anderen Übersetzungseinheit hast, wird sich der Linker nicht beschweren).

    setw(2) setzt durch, dass die nächste Streamausgabe zwei Zeichen breit ist, der Rest wird mit Nullen aufgefüllt (dafür das setfill('0') zuvor).
    Das kannst du aber auch hier nachlesen (und alle anderen Fragen zur Standardbibliothek beantwortet dir die Seite auch):
    http://www.cplusplus.com/reference/iostream/manipulators/setw/



  • Okay danke nochmal.
    Hab nun alles verstanden.



  • Offiziell sollte man statt "static" bei Funktionen besser anonyme Namensbereiche verwenden (aber ich benutze sie auch nicht immer -):

    namespace
    {
    
    inline int hexCharToInt(char ch)
    {
      ...
    }
    
    }
    

Anmelden zum Antworten