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 ohnestream->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.