JPG => Stream => BMP



  • Ich möchte in einem Bildbetrachtungsprogramm JPG-Dateien anzeigen. Dazu muss ich die JPG ins BMP-Format konvertieren. Ich habe es mir einfach gemacht und die JPG zunächst als BMP gespeichert (dabei wird sie in das BMP-Format konvertiert) und anschließend die BMP wieder eingelesen und auf der HDD gelöscht.

    //  ##############################################
    //  ###  JPG-Datei in temporäre BMP kopieren   ###
    //  ##############################################
    int LeseJPG(char * szFileName, BOOL qMitDaten)
    {
    	CImage image;
    
    	HRESULT hResult1 = image.Load(_T(szFileName)); // JPG-Datei einlesen
    	if (hResult1 != S_OK) { return 1; } // Fehler beim LOAD JPG  
    
    	HRESULT hResult2 = image.Save(szTmpJpgBmp);
    	if (hResult2 != S_OK) { return 2; } // Fehler beim SAVE BMP
    
    	return 0; // OK temporäre BMP aus JPG erstellt
    }
    
    

    Nun möchte ich SAVE + LOAD über einen Stream realisieren.
    "Image.Save" kann auch Streams, aber wie geht das konkret ?
    Die BMP sollte dann in einem Puffer stehen.



  • Du bist hier im falschen Unterforum mit deiner Frage. Hier ist C++/cli mit .NET. Deine Frage wird sicher bald ins MFC-Forum verschoben.

    @hkdd sagte in JPG => Stream => BMP:

    Ich möchte in einem Bildbetrachtungsprogramm JPG-Dateien anzeigen. Dazu muss ich die JPG ins BMP-Format konvertieren.

    Nein, musst du nicht. CImage::Load() lädt auch JPEGs und CImage::Draw() zeichnets dir dorthin wo du es haben willst. Wenn du wirklich "raw" Pixels haben willst, gibt's CImage::GetBits().



  • @Swordfish ,
    das Programm macht eine Menge anderer Dinge. Die unterschiedlichen Dateiformate werden jeweils als BMP von den Lese-Routinen bereitgestellt und in dieser Form weiterverarbeitet. Meine alten JPG-Leseroutinen von der "Independent JPEG Group's Software" (damals unter Windows 98 mit VC98) lassen sich unter VS2017 nicht mehr benutzen. Deshalb habe ich für JPG eine andere Lösung gesucht und nun auch gefunden.
    Man kann die JPG als temporäre BMP speichern und so wieder einlesen. Ich habe nach der Möglichkeit gesucht, anstelle des SAVE + LOAD diese Aufgabe über einen internen Stream zu erledigen, da das wesentlich schneller geht. Mit etwas Suchen und Probieren habe ich nun eine Lösung gefunden. Vielleicht braucht das noch einmal jemand, deshalb hier diese JPG => BMP Routine.

    //  ##############################################
    //  ###  JPG-Datei als BMP in BMP-Puffer       ###
    //  ##############################################
    BYTE * LeseJPG(char * szFileName, BOOL qMitDaten)
    {
    	CImage image;
    	IStream *stream = NULL;
    
    	HRESULT hr = image.Load(_T(szFileName)); // JPG-Datei einlesen
    	if (hr != S_OK) { return NULL; } // Fehler beim LOAD JPG  
    
    	hr = CreateStreamOnHGlobal(0, TRUE, &stream);
    	if (!SUCCEEDED(hr))	{ return NULL; } // Fehler bei CreateStreamOnHGlobal
    
    	hr = image.Save(stream, Gdiplus::ImageFormatBMP);  // JPG-Image als BMP => Stream
    	if (hr != S_OK) { return NULL; } // Fehler beim SAVE BMP => Stream  
    
    	ULARGE_INTEGER liSize;
    	IStream_Size(stream, &liSize); // Länge der BMP im IStream
    	DWORD len = liSize.LowPart;
    	IStream_Reset(stream); // Für Lesen der BMP an Anfang setzen
    
    	BYTE * lpPuBMP = new BYTE[len];  // Pointer auf BMP-Puffer im Speicher
    	IStream_Read(stream, &lpPuBMP[0], len); // BMP aus Stream in Puffer lesen
    	stream->Release();
    
    	return lpPuBMP;  // Pointer auf BMP-Puffer im Speicher
    
    } // Ende LeseJPG
    


  • Dein Code hat ein leak. Wenn image.Save( stream, Gdiplus::ImageFormatBMP) fehlschlägt springst du aus der Funktion ohne stream->Release() aufzurufen.
    Abgesehen davon ist es kein guter Stil, einen Zeiger zurückzugeben, den der Aufrufer der Funktion freigeben muss.



  • Der Kot oder das ganze Unterfangen ist sowieso ziemlich sinnlos.


Anmelden zum Antworten