trichview.com

trichview.support.examples




Example: How to save/load images  in RTF as PNG


Return to index


Author

Message

Sergey Tkachenko

Posted: 11/04/2003 17:35:01


RTF files can contain graphics in the following format: bitmap, metafile,

jpeg, png.

Import/export of all these formats except for png are supported by TRichView

directly.

But PNG is not, because Delphi does not offer standard implementation of

png.

But with help of events you can save and load PNG images in RTF.


Why PNG? PNG offers a good compression. While True-Color bitmaps can be

really huge (especially considering the fact that image size in RTF is twice

larger than in a graphic file), PNG can be by hundreds times smaller.


PNG images are supported by Word97 and newer. When Word saves a PNG image,

at also saves a metafile duplicate allowing less advanced applications to

read this image.

The example below does not save a duplicate, because the main reason why you

may wish to use PNG is to make more compact RTF code.


This example uses a free PNG class by Gustavo Huffenbacher Daud:

http://pngdelphi.sourceforge.net/


uses RVRTF, RVRTFProps, RVItem, CRVData, RVFMisc;


1) Reading PNG. Can be useful even if you do not want to export images in

RTF as PNGs (by


Create a form's procedure:


procedure TForm3.RichViewEdit1CustomImageItem(RVData: TCustomRVData;

  Graphic: TGraphic; Hypertext: Boolean; var item: TCustomRVItemInfo;

  var FreeGraphic: Boolean; RTFPicture: TRVRTFPicture);

var png: TPngObject;

begin

  if RTFPicture.PicType=rtf_pict_PNG then begin

    png := TPngObject.Create;

    try

      png.LoadFromStream(RTFPicture.FData);

      Graphic := png;

      FreeGraphic := True;

    except

      png.Free;

    end;

  end;

  if Graphic=nil then

    exit;

  if Hypertext then

    item := TRVHotGraphicItemInfo.CreateEx(RVData, Graphic, rvvaBaseline)

  else

    item := TRVGraphicItemInfo.CreateEx(RVData, Graphic,  rvvaBaseline);

end;


In Form's OnCreate, assign it to

RichViewEdit1.RTFReadProperties.OnCustomImageItem:


RichViewEdit1.RTFReadProperties.OnCustomImageItem :=

RichViewEdit1CustomImageItem;


2) Writing PNG. This code will save all bitmaps and PNG in document in RTF

as PNG.


Event RichViewEdit1S.OnaveItemToFile


procedure TForm3.RichViewEdit1SaveItemToFile(Sender: TCustomRichView;

  const Path: String; RVData: TCustomRVData; ItemNo: Integer;

  SaveFormat: TRVSaveFormat; Unicode: Boolean; var OutStr: String;

  var DoDefault: Boolean);

var Stream: TMemoryStream;

    gr: TGraphic;

    png: TPngObject;

    item : TRVGraphicItemInfo;

begin

  if (SaveFormat<>rvsfRTF) then

    exit;

  if (RVData.GetItemStyle(ItemNo)<>rvsPicture) and

     (RVData.GetItemStyle(ItemNo)<>rvsHotPicture) then

    exit;

  item := TRVGraphicItemInfo(RVData.GetItem(ItemNo));

  gr := item.Image;

  if not (gr is TBitmap) and not (gr is TPngObject) then

    exit;

  if (gr.Width=0) or (gr.Height=0) then

    exit;

  if gr is TBitmap then begin

    png := TPNGObject.Create;

    png.Assign(gr);

    end

  else

    png := TPNGObject(gr);

  try

    Stream := TMemoryStream.Create;

    try

      png.SaveToStream(Stream);

      OutStr := Format('{\pict\pngblip\picw%d\pich%d',

[png.Width,png.Height]);

      if item.ImageWidth>0 then

        OutStr := Format('%s\picscalex%d', [OutStr,

Round(item.ImageWidth*100/png.Width)]);

      if item.ImageHeight>0 then

        OutStr := Format('%s\picscaley%d', [OutStr,

Round(item.ImageHeight*100/png.Height)]);

      OutStr := OutStr+' '+RVFSavePicture(png)+'}';

      DoDefault := False;

    finally

      Stream.Free;

    end;

  finally

    if png<>gr then

      png.Free;

  end;

end;





Powered by ABC Amber Outlook Express Converter