Search code examples
c++buildercodecfiremonkey-fm3c++builder-xe5tbitmap

How to add new Bitmap format to TBitmapCodecManager


I have written a class for reading and writing PPM files (don't ask, I didn't chose this format). I would like it to be a part of the TBitmap loading/saving system.

Does any one know how I can add this support? Do I really have to write/install a full codec?

SOLUTION:

With Remy Lebeau post I managed to write and register a codec. However all the needed functions aren't documented so It needed some trial/error to get it to work.

To register the new codec you need to use the static member RegisterBitmapCodecClass of TBitmapCodecManager like this.

TBitmapCodecManager::RegisterBitmapCodecClass(".ppm","portable pixmap",true,__classid(TMyCodec));

The codec need these functions to be defined:

class TMyCodec : public TCustomBitmapCodec {

    public:
        bool __fastcall LoadFromStream(System::Classes::TStream* const AStream, Fmx::Surfaces::TBitmapSurface* const Bitmap);
        bool __fastcall LoadFromFile(const System::UnicodeString AFileName, Fmx::Surfaces::TBitmapSurface* const Bitmap);

        bool __fastcall SaveToFile(const System::UnicodeString AFileName, Fmx::Surfaces::TBitmapSurface* const Bitmap, const PBitmapCodecSaveParams SaveParams = (PBitmapCodecSaveParams)(0x0));
        bool __fastcall SaveToStream(System::Classes::TStream* const AStream, Fmx::Surfaces::TBitmapSurface* const Bitmap, const System::UnicodeString Extension, const PBitmapCodecSaveParams SaveParams = (PBitmapCodecSaveParams)(0x0));

        __classmethod System::Types::TPointF __fastcall GetImageSize(const System::UnicodeString AFileName);
        __classmethod bool __fastcall IsValid(System::Classes::TStream* const AStream);

        bool __fastcall LoadThumbnailFromFile(const System::UnicodeString AFileName, const float AFitWidth, const float AFitHeight, const bool UseEmbedded, Fmx::Surfaces::TBitmapSurface* const Bitmap);
};

The class Fmx::Surfaces::TBitmapSurface has no trace of documentation, but the IDE provided me with available functions. I figured the Pixels[x][y] array is used to read/write the pixels.

After the class has been registered, you can read the new image type as usual with TBitmap->LoadFromFile("");

Enjoy!

PS. Those who voted to close this, please put in a comment to why? How can we improve if we don't know what mistakes we do?


Solution

  • You need to derive a new class from TCustomBitmapCodec and implement the virtual LoadFrom...() and SaveTo...() methods, and then register the class at app startup using TBitmapCodecManager::RegisterBitmapCodecClass().