I have a routine procedure DrawStuff(ACanvas: TCanvas; const ARect: TRect)
that draws something to a specified rectangle on a TCanvas. At the moment I call DrawStuff
with a PaintBox's canvas. Now I'm adding a Save as
option, in which the user shall be able to select from a variety of file formats (bmp, wmf, jpg, ... - preferrably as many TGraphic descendants as possible) to save the results of DrawStuff
to.
Drawing to a TMetafile
and saving that as "bla.bmp" or Assign
ing it to a TPicture
doesn't work correctly - e.g. it produces files with extension ".bmp" that aren't bit开发者_开发问答maps. Right now I can't figure a solution that doesn't involve special-casing every single file format:
- bmp - Use
TBitmap.Canvas
. - wmf/emf: Use
TMetafileCanvas
. - etc. etc.
Do you know have any ideas for me?
I guess a "dumb" conversion would probably as simple as this :
type
TGraphicTypeEnum = (gteBMP, gteJPG, gteTIF, gtePNG);
procedure SaveGraphicAs(AGraphic : TGraphic; AGraphicType : TGraphicTypeEnum; AFileName : String);
var vGraphicClass : TGraphicClass;
vTargetGraphic : TGraphic;
vBmp : TBitmap;
begin
case AGraphicType of
gteBMP : vGraphicClass := TBitmap;
gtejpg : vGraphicClass := TJPEGImage;
gtetif : vGraphicClass := TWICImage;
gtepng : vGraphicClass := TPngImage;
else
// EXIT; or raise...
end;
if aGraphic is vGraphicClass then //As suggested by Rob Kennedy
AGraphic.SaveToFile(AFileName)
else
begin
vBmp := nil;
vTargetGraphic := vGraphicClass.Create;
try
vBmp := TBitmap.Create;
vBmp.Assign(AGraphic);
vTargetGraphic.Assign(vBmp);
vTargetGraphic.SaveToFile(aFileName);
finally
vTargetGraphic.Free;
vBmp.Free;
end;
end;
end;
Assigning to a TPicture didn't work, as when you assign to a TPicture, TPicture will convert the graphic to the class you are assigning from.
Note that in my example, there is 2 layers of conversion as the original image is converted to bitmap before being converted to the final format. There can be quite a bit of loss of information in the process. Most (all?) graphic type know how to convert to and from TBitmap, but TJPEGImage has no idea how to convert to TPngImage and vice versa.
More efficient conversion method can be developed that keeps transparency and other effects specific to a file format, but that is beyong my knowledge. But depending on your needs, that might be sufficient.
精彩评论