[How to] How to use PNG and GIF images in TRichView

Demos, code samples. Only questions related to the existing topics are allowed here.
Sergey Tkachenko
Site Admin
Posts: 17557
Joined: Sat Aug 27, 2005 10:28 am
Contact:

[How to] How to use PNG and GIF images in TRichView

Post by Sergey Tkachenko »

PNG images have the following advantages:
- small size (advantage over bitmaps)
- not limited to 256 colors (advantage over gifs)
- lossless compression (advantage over jpegs)
- semitransparency (advantage over all the formats above)
Disadvantage:
- cannot store animation.

For Delphi 4-2007
To use PNG images in TRichView, you need some thirdparty graphic class representing them. For example, you can use free TPngObject (by Gustavo Huffenbacher Daud) http://pngdelphi.sourceforge.net/
(Version 1.564 can be downloaded here:
http://www.trichview.com/resources/thir ... gimage.zip )
It has almost all required functions. The code below assumes that you use this class, but it can be applied to any other class.
For Delphi 2009 or newer
Delphi 2009 has built-in PNG support: TPngImage class from PngImage unit.
Update: starting from TRichView 14.5, TRichView uses TPngImage automatically. So, for Delphi 2009+, no additional code is required to enable PNG support.

Steps to enable PNG support in Delphi 4-2007

1) Add PngImage in "uses" of one of your units

2) Call RegisterClass(TPngObject). It's necessary to load PNG images from RVF files (even if you do not use RVF files, RVF format is used to copy-paste from the Clipboard and in drag&drop)

3) By default, all images are saved to HTML conveted to Jpegs. PNG is a WWW format, so this conversion is undesirable. Call RVGraphicHandler.RegisterHTMLGraphicFormat(TPngObject); to save images in PNG files (RVGraphicHandler is defined in RVFuncs unit)

4) Call RVGraphicHandler.RegisterPngGraphic(TPngObject); It allows loading PNG images from RTF files and saving PNG images to RTF files without converting to bitmaps or metafiles

5) Usually you need to call TPicture.RegisterFileFormat to associate the class with its file extension. But it's not needed for TPNGObject, because this work is already done in the file where it's implemented: TPicture.RegisterFileFormat('PNG', 'Portable Network Graphics', TPNGObject);. This association is required for many tasks (creating image files when saving HTML, loading external images when loading RTF or HTML, listing in the file filter for "Insert Picture" in RichViewActions, etc.)

6) (optional step) enable high-quality resizing of non-transparent PNG images, see http://www.trichview.com/forums/viewtop ... 153#p34153

The code in steps 2-5 must be called one time before the first file operation. For example, it can be placed in the initialization section of the main form's unit.

Note 1: Only the step 4 is specific for PNG images. All other steps must be applied for any third-party graphic class.

Update 2013-Jun-7: The information above is updated for compatibility with TRichView 14.5:
- now, TRichView uses TPngImage automatically in Delphi 2009+ (unless you define RVDONOTUSEPNGIMAGE in RV_Defs.inc)
- RVGraphicHandler should be used instead of the old functions

Update 2017-Nov-21: the step 6 is added
Last edited by Sergey Tkachenko on Fri Jun 07, 2013 2:50 pm, edited 5 times in total.
Sergey Tkachenko
Site Admin
Posts: 17557
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Features of Gif images:
- small size;
- may be animated;
- may have transparent areas;
- limited to 256 colors (each animation frame may have up to 256 colors, but frames may be in different palettes)

Free Delphi libraries supporting GIF, useful for Delphi 4-2006:

1) Anders Melander's TGifImage

http://www.torry.net/vcl/graphics/gif/gifimage.exe (original)
http://www.trichview.com/resources/thir ... fimage.zip (update - required)
To support animation, include RVGifAnimate unit in your project.
(and set RichView.AnimationMode = rvaniOnFormat).

Update March-27-2008: Anders Melander's web site is reborn. You can find the latest information about TGifImage here: http://melander.dk/delphi/gifimage/

2) TJvGifImage from JEDI's JVCL
http://jvcl.sourceforge.net
To support animation, include RVJvGifAnimate unit in your project.
(and set RichView.AnimationMode = rvaniOnFormat).

Delphi 2007 or newer
Delphi 2007 has TGifImage class in GifImg unit.
To support animation, include RVGifAnimate2007 unit in your project.
(and set RichView.AnimationMode = rvaniOnFormat).
Last edited by Sergey Tkachenko on Tue Jan 26, 2010 8:57 pm, edited 2 times in total.
Sergey Tkachenko
Site Admin
Posts: 17557
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Delphi 2007 supports gif images. It includes TGifImage class (defined in GifImg unit). This is an improved version of Anders Melander's TGifImage.

To support animation using this class, include RVGifAnimate2007.pas in your project.
martindholmes
Posts: 131
Joined: Mon Aug 29, 2005 12:03 pm

Typo in documentation

Post by martindholmes »

The TRichView Help file has this:

Unit RVMisc.

procedure RV_RegisterPngGraphic(ClassType: TGraphicClass);

whereas the correct unit is CRVData, as you mentioned above.


Cheers,
Martin
Sergey Tkachenko
Site Admin
Posts: 17557
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Thanks Martin, it will be corrected.

Also I'd like to mention that Delphi 2009 includes PNG class (TPngImage) in VCL, so thirdparty class is not required any more.
Sergey Tkachenko
Site Admin
Posts: 17557
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Migrating from TPngObject to TPngImage

This information is useful if:
- you have RVF documents containing PNG images saved by applications compiled in Delphi 4...2007 (using TPngObject class);
- you upgraded to Delphi 2009 or newer.

Problem
In older versions of Delphi, you used TPngObject class for PNG images, and the name of this this class name was saved RVF files to identify PNG images.
In Delphi 2009/2010, the class for PNG is not TPngObject but TPngImage. TPngObject is declared, but it is declared not as a class, but as an alternative name of TPngImage:

Code: Select all

  TPNGObject = TPngImage 
.
Because of this, even if you add the line

Code: Select all

RegisterClass(TPngObject)
it will not help, because this line still registers TPngImage instead of TPngObject. So, when loading RVF file, 'TPngImage' class is still unknown for TRichView.

Solution
Create your own class with the name TPngObject and register it:

Code: Select all

type TPngObject = class (TPngImage); 
... 
RegisterClass(TPngObject); 
All other registration code can still be for TPngImage:

Code: Select all

  RegisterClass(TPngImage); 
  RV_RegisterHTMLGraphicFormat(TPngImage); 
  RV_RegisterPngGraphic(TPngImage); 
Stefaan
Posts: 30
Joined: Mon Feb 16, 2009 11:36 am

Post by Stefaan »

Another possibility is using the method Classes.RegisterClassAlias to register TPNGObject as an alias for TPngImage.

Delphi code:

Code: Select all

RegisterClassAlias(TPngImage, 'TPNGObject');
C++ code:

Code: Select all

RegisterClassAlias(__classid(TPngImage), "TPNGObject");
Sergey Tkachenko
Site Admin
Posts: 17557
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Thank you. Your solution looks much better, because images will be loaded in TPngImage.
Alexander_Dober
Posts: 130
Joined: Fri Mar 04, 2011 3:44 am

Post by Alexander_Dober »

Does this still apply to Delphi XE and TRichView 13.6?

Noticed that the usage of PNGs isn't working at the moment. Searched the forum and found this thread, but it seems not to work to call

Code: Select all

   RegisterClass(TPngImage); <- incompatible types
   RV_RegisterHTMLGraphicFormat(TPngImage); <- unknown, although CRVFData is in uses
   RV_RegisterPngGraphic(TPngImage); <- unknown, although CRVFData is in uses
   TPicture.RegisterFileFormat('PNG', 'Portable Network Graphics', TPngImage);
Sergey Tkachenko
Site Admin
Posts: 17557
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Did you include PngImage in "uses"?

These functions are defined in CRVData.pas, not in CRVFData.pas

TPicture.RegisterFileFormat is not needed (it is already called in PngImage)
Alexander_Dober
Posts: 130
Joined: Fri Mar 04, 2011 3:44 am

Post by Alexander_Dober »

Sergey Tkachenko wrote:Did you include PngImage in "uses"?
Yes, I did. Is the order of any imporatnce?
Sergey Tkachenko wrote: These functions are defined in CRVData.pas, not in CRVFData.pas
My bad, I had the one with an "F" in uses. Now these two calls semm to be ok, but RegisterClass still fails.
Sergey Tkachenko
Site Admin
Posts: 17557
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

What's exactly shown in the error message?
Alexander_Dober
Posts: 130
Joined: Fri Mar 04, 2011 3:44 am

Post by Alexander_Dober »

translated:

Code: Select all

[DCC Fehler] <my_unit>: E2010 incompatible types: 'tagWNDCLASSW' and 'class of TPngImage'
for UnRegisterClass(TPngImage); in the finalization-part:

Code: Select all

[DCC Fehler] <my_unit>: E2010 incompatible types: 'PWideChar' and 'class of TPngImage'
Sergey Tkachenko
Site Admin
Posts: 17557
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Aha. You need RegisterClass from Classes.pas, but RegisterClass from Windows.pas is used.
Change the order of units in "uses", move Windows before Classes.
Alexander_Dober
Posts: 130
Joined: Fri Mar 04, 2011 3:44 am

Post by Alexander_Dober »

Ok, that way it works.

Do I need to call anything to unregister?
RV_UnRegisterHTMLGraphicFormat(TPngImage);
RV_UnRegisterPngGraphic(TPngImage);
or so?
Post Reply