none
CBitmap als GIF Datei speichern RRS feed

  • Frage

  • Hallo Forum

    Ich suche heute schon den ganzen Tag im Internet, um eine einfache Methode zum Abspeichern eines CBitmap als GIF Datei zu finden. Man kann sich die CxImage und CImage Bibliotheken herunterladen mit dem Erfolg, dass diese Dinger richtige Mollochs sind und ich natürlich überall diverse LIBs und DLLs vermisse.

    Ich arbeite noch unter VC++ 6.0 mit MFC. Auf Codeproject GAB es mal einen guten Artikel über LZW und GIF, der aber mittlerweile gelöscht ist.

    Hat jemand eine kleine Kompressionslibrary für Bitmap -> GIF parat. Was nehme ich am besten (ich will nur GIF abspeichern, keine Bilder laden, keine Bildtransformationen, ...).

    Es kann zur Not auch JPG sein (es handelt sich um technische Diagramme, JPG macht die nicht so besonders gut).

    Grüße

    FireHeart

    Freitag, 23. April 2010 11:13

Antworten

  • GDI+:

     GdiplusStartupInput gdiplusStartupInput;
     ULONG_PTR gdiplusToken;
     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
    
     Bitmap *pBitmap = Bitmap::FromHBITMAP(
              (HBITMAP)bmp.GetSafeHandle(),
              (HPALETTE)pPalette->GetSafeHandle());
    
     //get encoder CLSID
     CLSID Clsid;
     if(fileDlg.GetFileExt().MakeUpper() == _T("BMP"))
      GetEncoderClsid(L"image/bmp", &Clsid);
     else if(fileDlg.GetFileExt().MakeUpper() == _T("GIF"))
      GetEncoderClsid(L"image/gif", &Clsid);
     else if(fileDlg.GetFileExt().MakeUpper() == _T("JPG"))
      GetEncoderClsid(L"image/jpeg", &Clsid);
    
     //save to file with current color
     BSTR bstrFileName = fileDlg.GetPathName().AllocSysString();
     pBitmap->Save(bstrFileName, &Clsid, NULL);
    
     //clear and shutdown GDI+
     SysFreeString(bstrFileName);
     GdiplusShutdown(gdiplusToken);

    Siehe auch: http://msmvps.com/blogs/peterritchie/archive/2006/09/25/Save-CBitmap-to-File.aspx


    Jochen Kalmbach (MVP VC++)
    Freitag, 23. April 2010 15:29

Alle Antworten

  • GDI+:

     GdiplusStartupInput gdiplusStartupInput;
     ULONG_PTR gdiplusToken;
     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
    
     Bitmap *pBitmap = Bitmap::FromHBITMAP(
              (HBITMAP)bmp.GetSafeHandle(),
              (HPALETTE)pPalette->GetSafeHandle());
    
     //get encoder CLSID
     CLSID Clsid;
     if(fileDlg.GetFileExt().MakeUpper() == _T("BMP"))
      GetEncoderClsid(L"image/bmp", &Clsid);
     else if(fileDlg.GetFileExt().MakeUpper() == _T("GIF"))
      GetEncoderClsid(L"image/gif", &Clsid);
     else if(fileDlg.GetFileExt().MakeUpper() == _T("JPG"))
      GetEncoderClsid(L"image/jpeg", &Clsid);
    
     //save to file with current color
     BSTR bstrFileName = fileDlg.GetPathName().AllocSysString();
     pBitmap->Save(bstrFileName, &Clsid, NULL);
    
     //clear and shutdown GDI+
     SysFreeString(bstrFileName);
     GdiplusShutdown(gdiplusToken);

    Siehe auch: http://msmvps.com/blogs/peterritchie/archive/2006/09/25/Save-CBitmap-to-File.aspx


    Jochen Kalmbach (MVP VC++)
    Freitag, 23. April 2010 15:29
  • Hallo Jochen Über das GDI+ bin ich bei meinen Recherchen auch schon gestolpert. Ich frage mich nur, wie ich alle notwendigen LIBs, DLLs und Hs bekomme...meine VC++6.0 Installation kennt das nämlich noch gar nicht... Grüße Richie
    Montag, 26. April 2010 05:24
  • Du Verwendest halt ein produkt, das ca. 13 Jahre alt ist...

    Aber das GDI+ Zeugs sollte im letzten gültigen PSDK enthalten sein: (Februar 2003)

    http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm


    Jochen Kalmbach (MVP VC++)
    Montag, 26. April 2010 06:03
  • Hallo Jochen Du hast recht mit den 13 Jahren. Ich verwende den guten 6.0er aus historischen Gründen, weil wir unsere Produkte damals zu entwickeln begonnen haben und derzeit halt wissen, dass die Software mit dieser Entwicklungsumgebung auch stabil läuft. Ich hab meine schlechten Erfahrungen mit der Installation von SDKs...die drehen im System so viel um, dass die alten Sachen nicht mehr funktionieren. Daher hab ich mir die SDK mal runtergeladen, dann alle CABs händisch entpackt und dann in den tausend weiteren CABS die dabei rausgekommen sind mal die GDIPLUS.LIB gesucht. Soweit so gut, das funktioniert auch. Nur compilieren kann ich das Zeugs nicht, weil der Compiler sich in den neuen H Dateien nicht auskennt. Er kennt z.B. THIS_FILE nicht und auch mit dem "GDI+:" Statement hat er nichts angefangt. Gibt es einen kurzen Weg, diese Probleme zu beseitigen? Grüße Richie
    Montag, 26. April 2010 06:08
  • Die Installation des PSDKs sollte nichts an Deiner VC Umgebung ändern... das musst Du dann noch naträglich von Hand machen. Die Header und LIBs sind im PSDK immer aufeiander abgestimt, deshalb rate ich Dir, diese auch zu verwenden.

    Man kann es natürlich auch so hinbekommen, aber das ist sehr viel Handarbeit...


    Jochen Kalmbach (MVP VC++)
    Montag, 26. April 2010 06:11
  • so... neues SDK ist jetzt mal installiert. Ich habe noch NICHT die environment variablen aktiviert. Wenn ich jetzt das neue "stdafx.h" angebe...aber dann meint er "unexpected end of file while looking for precompiled header directive"...tja, ich kann mich ja erinnern, dass das mit den SDKs nicht so einfach war.. Grüße Richie
    Montag, 26. April 2010 06:56
  • Hallo Fire-Heart!
     
    > so... neues SDK ist jetzt mal installiert. Ich habe noch NICHT die
    > environment variablen aktiviert. Wenn ich jetzt das neue "stdafx.h"
    > angebe...aber dann meint er "unexpected end of file while looking for
    > precompiled header directive"...tja, ich kann mich ja erinnern, dass das
    > mit den SDKs nicht so einfach war.. Grüße Richie
     
    Was für ein *neues* stdafx.h*???? Das kommt nicht mit dem PSDK... das
    gehört zu DEINEM Projekt!
     
    Das hat eigentlich nix mit dem PSDK zu tun... schau doch mal in
    Tools|Options|Vc++ DIretories ob da das neue oder alte PSDK eingetragen ist.
     
    Über Umgebungsvariablen würde ich das soweiso nicht machen...
     
     
    Greetings
    Jochen
     

    Jochen Kalmbach (MVP VC++)
    Montag, 26. April 2010 06:59
  • Hallo Jochen Tut mir ja echt schon leid, dass ich dieses Forum für diese administrativen Zwecke missbrauche. So wie ich das jetzt verstehe, passiert ja eigentlich beim "Installieren" des PSDK nichts weiter, als dass er eine riesen Menge von Dateien (includes, libs, ...) in ein zusätzliches Verzeichnis stellt. Das hab ich ja jetzt mal soweit gemacht. Dann muss ich dem Compiler natürlich sagen, dass es zusätzliche "includes" gibt, damit er das Zeugs auch findet. Das hab ich jetzt mit "Tools"->"Options"->"Directories" gemacht. Das hilft natürlich gar nix. Ich kriege meine 60 Fehler/Warnmeldungen, weil er es nicht schafft, sich durch die "gdiplus.h" Dateien durchzucompilieren. Er kennt eine Menge von Definitionen usw. nicht...vermutlich weil's halt noch VC6.0 ist und irgendwo anders ein paar Definitionen fehlen. Bei meinen Recherchen über GDI+ hab ich allerdings schon erfahren, dass dieses Paket sehr wohl mit VC6.0 funktionieren kann. Woran könnte es jetzt noch fehlen? Grüße FireHeart
    Montag, 26. April 2010 08:42
  • Hallo Fire-Heart!
     
    > Bei meinen Recherchen über
    > GDI+ hab ich allerdings schon erfahren, dass dieses Paket sehr wohl mit
    > VC6.0 funktionieren kann. Woran könnte es jetzt noch fehlen?
     
    Du musst bei der Include-Reihenfolge *zuerst* das neue PSDK einbinden!!!
    Dann sollte es gehen...
     
     
    Greetings
    Jochen
     

    Jochen Kalmbach (MVP VC++)
    Montag, 26. April 2010 08:48
  • Hallo Jochen Natürlich hab ich alle Möglichkeiten der Includes (davor und danach) ausgeschöpft. Ich muss vielleicht noch erwähnen, dass sich mein PSDK so nennt: "Windows Server 2003 R2 Platform SDK" ist das überhaupt die Richtige? In der Folge bekomme ich, sobald ich die "gdiplus.h" einzubinden versuche, etwa 60 Alarme/Fehler. Die ersten darunter nennen sich " syntax error : identifier 'THIS_FILE' " und dann "function returns function" in der Datei "gdiplusbase.h" und alle Weiteren sind vermutlich eine Folge des ursprünglichen Problems. Grüße FireHeart
    Montag, 26. April 2010 08:59
  • Nein, Du hast das Falsche!

    Das letzte für VC6 war (wie schon gesagt) Feb 2003 (Windows Server 2003)!!! (ohne R2)

    http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm


    Jochen Kalmbach (MVP VC++)
    Montag, 26. April 2010 09:09
  • Hallo Jochen Ich krieg ne Krise. Jetzt hab ich das vorherige SDK wieder deinstalliert, das "neue" heruntergeladen und die "Core" Sachen installiert. Bei den Tools die Include Verzeichnisse wieder angegeben....das (fast) gleiche Bild. Ich hab jetzt nur noch 41 Fehler/Warnungen, aber die ersten paar sind gleich. Er kennt offenbar gewisse Definitionen nicht. Woran kann das jetzt noch liegen? Grüße FireHeart
    Montag, 26. April 2010 10:41
  • Wie heissen denn die Meldungen?
    Jochen Kalmbach (MVP VC++)
    Montag, 26. April 2010 11:35
  • Hallo Jochen Eine Anfrage bei Mircosoft selbst hat mir nur die Empfehlung gebracht, doch das VisualStudio 2010 express zu installieren...dann sollte es auch gehen. Naja, warum will ich auch Ferrari Reifen auf einen VW-Käfer montieren...ich soll doch den Ferrari kaufen und die Reifen dranmachen, oder? Ich hab mir mittlerweile über GIFFY.EXE beholfen, das ich einfach über _spawnlp aufrufe und meine BMP Datei in eine GIF Datei wandelt. Eine Endlösung ist das aber nicht, weil das sehr langsam ist und der Rechner in der Zeit, wo die hunderten BMPs umgewandelt werden nicht bedienbar ist, da GIFFY immer auch ein Fenster aufmacht und wieder zumacht und somit aber jede andere Anwendung den Fokus verliert. Die Sache wird wohl zum Lebenswerk.... Grundsätzlich jedoch: Das Einbinden von <gdiplus.h> in ein neues Projekt ohne weitere Tätigkeiten führt zu einer Flut von Alarmen und Fehlern. Der erste davon nennt sich "THIS_FILE" und "function returns function" in "gdiplusbase.h".
    Freitag, 30. April 2010 07:01
  • Hallo Fire-Heart!
     
    > Eine Anfrage bei Mircosoft selbst hat mir nur die Empfehlung gebracht,
    > doch das VisualStudio 2010 express zu installieren...
     
    Was erwartest Du auch anderes? VC6 ist seit einigen Jahren nicht mehr
    supported...
     
    Greetings
    Jochen
     

    Jochen Kalmbach (MVP VC++)
    Freitag, 30. April 2010 07:13
  • Zeig doch bitte etwas Code anstatt immer nur zu schreiben "geht nicht".
    Ich habe mit dem entsprechenden alten SDK+VC6+GdiPlus keine Probleme.
     
    Das es geht zeigen such genug Projekte auf CodeProject z.B.:
     
     

    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Freitag, 30. April 2010 11:42
    Moderator
  • Hallo Martin Ich befolge in meiner Verzweiflung ja eh alle eurer Direktiven. Ich habe jetzt das gdiplus Makro in mein VC6.0 eingebaut und ein leeres Projekt (Dialog based) erstellt. Anschließend das Makro aufgerufen. Wenn ich die Sache jetzt compilieren will, ist der erste Fehler in GDIPLUSINIT.H und zwar kennt er ULONG_PTR (undeclared identifier) nicht. Die weiteren Fehler sind wohl wieder auf diesen ersten zurückzuführen. Grüße FireHeart
    Montag, 3. Mai 2010 05:40
  • Dann verwendest Du wohl nicht das letzte SDK oder Du hast gdiplusinit.h vor den Windows Headerm eingesetzt.

    Ansonsten kannst Du es auch mit einem Hack versuchen und einen typedef ULONG_PTR ULONG; einbauen.

    Ich würde Dir raten Dein SDK auf den korrekten Stand zu bringen. Infos hast Du von Jochen bekommen.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Montag, 3. Mai 2010 06:14
    Moderator
  • Hallo Martin Ich hatte zuvor ja schon mal das falsche SDK installiert und dann mühevoll nochmals alles deinstalliert und die alte Version (Feb. 2003) installiert (Link von Jochen erhalten). Ich tippe aber ehrlich gesagt auch darauf, dass ich hier immer noch irgendwas Falsches hab. Was die Einstellungen der Workbench zu dieser neuen SDK betrifft, kann ich mich ja darauf beschränken, den neuen include Pfad hinzuzufügen (muss ganz oben stehen, hab ich mir sagen lassen), oder? Den Hack mit dem typedef hab ich natürlich auch ausprobiert...dann spießts halt woanders. Auf diese Weise krieg ich die Sache wohl nicht hin. Ich bin ja schon so weit, dass ich mir von Kollegen, die mit neueren VC Umgebungen arbeiten, eine DLL schreiben lasse, die ein CBitmap als GIF abspeichert, um den ganzen h-Dateien aus dem Wege zu gehen...aber vermutlich passen die Libraries dann auch nicht zusammen. Grüße FireHeart
    Mittwoch, 5. Mai 2010 06:32