Bitmaproutine allgemein gestallten für mehrere Bildformate
-
Hallo Community,
C++
Borland C++ Builder 2007Ich hab folgendes Problem.
Ich benutze eine GIFImage.pas datei, die es ermöglicht, das im normalen TImage
animierte GIF-Dateinen wiedergegeben werden.Nun dies funktioniert tadellos.
Nun wollte ich dies in mein bestehendes Programm einbinden.
Dort habe ich, da dies anfangs noch nicht möglich war, nur BMPs berücksichtigt.
Und diese Routinen müsste ich nun umstellen, dass sowohl BMPs als auch GIFs damit verarbeitet werden könnten.Ich komme leider jedoch nicht auf die lösung wie ich es umstellen muss.
Kann mir jemand einen Tipp geben oder nen Hinweis? oder ne LösungRoutinen sehen so aus:
Graphics::TBitmap *bmp; bmp = new Graphics::TBitmap(); ... bmp->LoadFromFile(Folder + fd.cFileName); if (bmp->Height != 32 || bmp->Width != 32) ShowMessage("Bildgröße muß 32x32 Pixel sein: " + (AnsiString)fd.cFileName); else { ImageListNeu->Add(bmp, NULL); pItem = ListView1->Items->Add(); ...
u
Graphics::TBitmap *bmp; bmp = new Graphics::TBitmap(); bmp->Height = 32; bmp->Width = 32; TBlobStream *pBS; ... bmp->LoadFromStream(pBS); if (bmp->Height == 32 && bmp->Width == 32) ImageListZT->Add(bmp, NULL);
Danke
Alex
-
Nimm TPicture::LoadFromFile oder TPicture::LoadFromStream:
std::auto_ptr <TPicture> picture (new TPicture); picture->LoadFromFile (...); String name = picture->Graphic->ClassName ();
Diese Methoden erstellen je nach Bedarf ein Objekt von TBitmap, TIcon, TJPEGImage, TGIFImage, TPNGImage oder jede beliebige andere von TGraphic abgeleitete Klasse, die sich entsprechend registriert hat.
-
std::auto_ptr <TPicture> picture (new TPicture); picture->Bitmap->Height = 32; picture->Bitmap->Width = 32; ... picture->Bitmap->LoadFromStream(pBS); //bmp->LoadFromStream(pBS);
Aber kommt mir irgendwie spanisch vor?1
Hab Probleme da ich das ganze in ne DAtenbank speicher als ftBlob
und dabei treten probleme auf, das die gif net regelkomform ist.
-
Klar, wenn du auf TPicture::Bitmap zugreifst, ist die schöne Polymorphie natürlich wieder dahin
Warum machst du es nicht einfach, wie ich vorschlug?Hab Probleme da ich das ganze in ne DAtenbank speicher als ftBlob
und dabei treten probleme auf, das die gif net regelkomform ist.Fehlermeldung?
-
Das ist die Fehlermeldung
Erste Gelegenheit für Exception bei $7C81EB33. Exception-Klasse EInvalidGraphic mit Meldung 'Bitmap ist ungültig'. Prozess Visu.exe (3860)
Erledigt sich der Fehler wenn ichs allgemeiner halte?
oder kann ich die diese Paradoxdatenbank als ftBlob nur Bitmapdateien abspeichern?!Ja in meinem Beispiel hab ich jetzt Bitmaps die ich laden will
und jetzt zusätzlich auchs Gifs.
Wenn ich jetzt deinen Vorschlag befolgestd::auto_ptr <TPicture> picture (new TPicture); picture->Height = 32; picture->Width = 32; picture->LoadFromStream(pBS);
Erhalte ich die Fehlermeldungen das ich auf TPicture::Height nicht zugreifen darf, sowie das ich net auf __Fastcall TPicture::LoadFromStream nicht zugreifen darf
?! ?!
-
aLeXanDer.. schrieb:
Erhalte ich die Fehlermeldungen das ich auf TPicture::Height nicht zugreifen darf, sowie das ich net auf __Fastcall TPicture::LoadFromStream nicht zugreifen darf
In puncto LoadFromStream habe ich mich geirrt; die Funktion kann ja nicht wissen, welchen Dateitypen sie zu laden versucht, daher geht das so nur über LoadFromFile.
Blobs dürften in der Lage sein, Daten aller Art zu speichern und nicht nur Bitmaps. Allerdings mußt du zugleich die Information vermerken, in welchem Dateiformat das Bild abgespeichert wurde. Unglücklicherweise ist die Liste der registrierten Graphikformate ein Implementationsdetail von Graphics.pas, und es existiert keine öffentliche Schnittstelle, um ein Format z.B. nach dem Klassennamen zu finden - TFileFormatsList.FindExt tut genau das, ist aber leider in der implementation-Sektion von Graphics.pas deklariert. Daher wird dir nicht viel mehr übrig bleiben, als sämtliche in Frage kommenden Graphikklassen manuell zu registrieren.
Das könnte z.B. so aussehen:
GraphicsSerializer.hpp:
#ifndef GraphicsSerializerHPP #define GraphicsSerializerHPP #include <Graphics.hpp> void saveGraphicsToStream (TPicture* picture, TStream* stream); void loadGraphicsFromStream (TPicture* picture, TStream* stream); #endif // GraphicsSerializerHPP
GraphicsSerializer.cpp:
#include <Graphics.hpp> #include <map> #include <utility> #include <stdexcept> #pragma hdrstop #include "GraphicsSerializer.hpp" #pragma package(smart_init) typedef TObject* (*createfunc_t) (void); template <class T> TObject* createObjectStatic (void) { return new T; } struct classinfo_t { TMetaClass* metaclass; createfunc_t createfunc; classinfo_t (TMetaClass* _metaclass, createfunc_t _createfunc) : metaclass (_metaclass) { createfunc = _createfunc; } template <class T> static classinfo_t get (void) { return classinfo_t (__classid (T), createObjectStatic <T>); } }; template <typename T, unsigned I> unsigned ArraySize (T(&)[I]) { return I; } // not thread-safe! static std::map <String, classinfo_t*> graphicClasses; static void registerGraphicClasses (void) { static classinfo_t classes[] = { classinfo_t::get <Graphics::TBitmap> (), classinfo_t::get <TIcon> (), classinfo_t::get <TMetafile> (), // insert more graphic classes here }; for (classinfo_t* i = classes, * e = classes + ArraySize (classes); i != e; ++i) graphicClasses.insert (std::pair <String, classinfo_t*> ( i->metaclass->ClassName (), i)); } #pragma startup registerGraphicClasses void saveGraphicsToStream (TPicture* picture, TStream* stream) { String classname = picture->Graphic->ClassName (); unsigned len = classname.Length (); // write class name first stream->Write (&len, sizeof (len)); stream->Write (classname.c_str (), len * sizeof (Char)); picture->Graphic->SaveToStream (stream); } void loadGraphicsFromStream (TPicture* picture, TStream* stream) { String classname; unsigned len; stream->Read (&len, sizeof (len)); classname.SetLength (len); stream->Read (classname.c_str (), len * sizeof (Char)); std::map <String, classinfo_t*>::const_iterator i = graphicClasses.find (classname); if (i == graphicClasses.end ()) throw std::runtime_error (AnsiString ().Format ( "Graphic class '%s' not found", ARRAYOFCONST ((classname))).c_str ()); // use a dynamic_cast so that an exception is thrown if the object's // type does not match picture->Graphic = &dynamic_cast <TGraphic&> (*i->second->createfunc ()); picture->Graphic->LoadFromStream (stream); }
main.cpp:
#include <vcl.h> #include <tchar.h> #include <memory> #include <map> #include <cstdio> #pragma hdrstop #include "GraphicsSerializer.hpp" int _tmain (void) { std::auto_ptr <TPicture> picture (new TPicture); std::auto_ptr <TStream> stream (new TMemoryStream); // Create a bitmap object (which happens implicitly by accessing // TPicture::Bitmap) and change its size. picture->Bitmap->SetSize (256, 256); // Save the bitmap into the stream. saveGraphicsToStream (picture.get (), stream.get ()); // Remove the old TPicture object and create a new one. picture.reset (new TPicture); // Now load our graphic from the stream again. stream->Position = 0; loadGraphicsFromStream (picture.get (), stream.get ()); std::_putts (Format ("The class name is '%s'", ARRAYOFCONST ((picture->Graphic->ClassName ()))).c_str ()); return 0; }