trichview.com

trichview.support




Re: Can't show gif image in a rtf file


Return to index


Author

Message

Sergey Tkachenko

Posted: 02/26/2004 21:40:29


> Hi,

>

> I am writing a application to allow user create a template document and

then

> generate the document on fly using the data and images stored in database.

> I have two questions:

>

> 1) when user insert a image into the template using RVEditor, can I add

some

> Identifier (eg \ImgIDxxxx ) into the rtf file so that I can replcae the

image

> later?


You can only change saving images in RTF completely in OnSaveItemToFile.

Check if the saved item is a graphic item, and SaveFormat=rvsfRTF, and

return a code to save in OutStr.


(

you can use

procedure RVSaveImageToRTF(Stream: TStream; TwipsPerPixel: Double;

  Image: TGraphic; ImageWidth, ImageHeight: Integer; Options:

TRVRTFOptions);

defined in RVItem.pas to save image RTF code in Stream.

TwipsPerPixel parameter can be get as

function GetTwipsPerPixel: Double;

  var DC: HDC;

  begin

    DC := CreateCompatibleDC(0);

    if RichViewPixelsPerInch>0 then

      Result := (72*20) / RichViewPixelsPerInch

    else

      Result := (72*20) / GetDeviceCaps(DC, LOGPIXELSY);

    DeleteDC(DC);

  end;

)


>

> 2) When I replace the image with a gif image, I add

> {\pict\pngblip

> 47494638376194023603F00000000000FFFFFF2C000000.....} into the rtf file.

MSWord

> can display this rtf with gif image showing OK. But when I load this rtf

> into the Demo ActionTest.exe, the gif images were missing. JPEG image is

> OK. I am using Delphi5. I can insert and display a gif image using

TrvActionInsertPicture.


As you can see from the name of keyword, gif image is saved as PNG inside

RTF

(MS Word saves such images both as PNG and as Metafile, so TRichView reads

and inserts metafile image).

Unfortunately, Delphi does not have standard implementation of PNG images.

But if you will use a third party PNG class, you can read it from RTF.


The example was posted in trichview.support.examples several months ago (I

only corrected the declaration of RichViewEdit1CustomImageItem because a new

parameter was added to the event)


<<


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


Create a form's procedure:


procedure TForm3.RichViewEdit1CustomImageItem(RVData: TCustomRVData;

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

  var FreeGraphic: Boolean; RTFPicture: TRVRTFPicture;

  var  Name: String);

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.OnSaveItemToFile


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