Page 1 of 1

Transparency and Metafiles

Posted: Tue Mar 10, 2009 1:51 pm
by 10546565
I need to be able to scale reports for printing as poster size, and they contain images from TCharts. To make this look good, I would like to use WMF/EMF images in the chart, but because transparency is not supported when creating WMF/EMF images from TChart, the reports either look poor or, if I change graphic formats, pixelated.

This is a serious problems with transparency issues when creating WMF/EMF graphics from TCharts. This is a long term known issue (see quote of post below). I know you all are excited about new features, but this seems to be a long term problem with TChart, and it affects more than a handful of users.

Note the quote from below:
I've marked this feature to get priority so we can try to add it for the next TeeChart release. [dated Dec 9, 2005]
Is there an ETA on a fix for this?

Ed Dressel


I read in a post dated Nov 8, 2005:

"I have charts with transparent series . Whenever I try to get a metafile using teeCreateMetafile, the series are not transparent in the metafile. Is there something I am missing? "

and the response was:

"Yes, this is a known problem already listed to be fixed for future releases... I've marked this feature to get priority so we can try to add it for the next TeeChart release."[/quote]

Posted: Thu Mar 26, 2009 3:37 pm
by narcis
Hi Ed,

We have been investigating this request recently.

We found that this is not possible in GDI as metafiles only admit transparency for bitmaps drawn in them. So you could generate a bitmap from a chart and copy the bitmap into a metafile. This would work but you'd loose metafile's resolution.

It is possible in GDI+ but results are not much accurate. You can try a chart with some transparency with this code:

Code: Select all

uses TeeGDIPlus, TeeEmfOptions;

procedure TForm1.FormCreate(Sender: TObject);
var g: TGDIPlusCanvas;
begin
  g:=TGDIPlusCanvas.Create;
  Chart1.Canvas:=g;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  if SaveDialog1.Execute then
  with TEMFExportFormat.Create() do
  begin
    try
      Panel := Chart1;
      Width := Chart1.Width;
      Height := Chart1.Height;
      Enhanced := true;
      SaveToFile(SaveDialog1.FileName);
    finally
      Free;
    end;
  end;
end;
Another option would be sending the GDI+ canvas directly to the printer without using metafiles nor bitmaps (Chart1.Draw(Printer.Canvas,R)). However, not using metafiles you'll have to manually rescale line, font, etc. sizes, which is what metafiles do.

If you know of a better way (or code) for generating metafiles with transparency please let us know.

Thanks in advance.

Posted: Thu Mar 26, 2009 10:58 pm
by 10546565
Thank you for the response. I appreciate your research.

I generate images for reports and they have to go to the intermediate stage of a graphic object.

Is there a way of increasing the density (pixels per inch) of a TPNGImage or TBitmap? This could also help solve the problem.

Ed Dressel

Posted: Sat Mar 28, 2009 5:03 am
by 10047094
Unfortunately, you cannot "increase the pixels per inch". I mean, you can make the image larger, and for each pixel add n pixels of the same color around it, but you will not get any better resolution. That is just the equivalent of a stretchDraw.

Narcis is right, if Metafiles cannot handle transparency (which I am not sure of) the only solution is to render the TChart at a larger size. If Steema could change the signature to

Chart.SaveAsBitmap(scaleFactor) where the width, height and ALL elements of the chart (fonts, line thicknesses etc) were rendered at the current size multiplied by the scale factor, that could help.

The other solution is for TChart to offer an option to render the transparent portions (usually a particular series) as a bitmap onto the metafile. Recognizing that the bitmap portions won't scale "properly" that still allows most elements to be vectorized (text, axis lines, grid lines etc) while still allowing the shapes of the series to be transparent. Since the series themselves are generally simple shapes (rectangles for bar charts, dots etc) those could be bitmaps embedded in teh metafile and still look okay in the end.

Posted: Sun Mar 29, 2009 12:08 am
by 10546565
Unfortunately, you cannot "increase the pixels per inch".
Okay, but why not? Is this a Windows limitation?
Chart.SaveAsBitmap(scaleFactor) where the width, height and ALL elements of the chart (fonts, line thicknesses etc) were rendered at the current size multiplied by the scale factor, that could help.

The other solution is for TChart to offer an option to render the transparent portions (usually a particular series) as a bitmap onto the metafile.
Both of those would work--I prefer the second method as it would reduce the size of the image--some reports I create can have a large number of images and when printing to a PDF, this becomes an issue.

Ed Dressel

Posted: Sun Mar 29, 2009 12:37 am
by 10047094
Is this a windows limitation
Think of it more a a law of physics. You don't get something for nothing :-)

Seriously, if you blow up a grainy image, you just get a larger version of a grainy image. You can never "increase the resolution" of the image. For instance, if your original image was

12
34

and you blow it up by two you get
1122
1122
3344
3344

that is not higher resolution, you cannot get better pixels per inch, you are just enlarging the image.

You can do all sorts of tricks to interpolate between adjacent values so they transition in a smoother manner, but that is just an estimation.

In order to get higher res you have to re-render from scratch at the higher resolution. Once you have transitioned from the metafile (assume infinite res) to a lower res bmp, you cannot take that lower res bmp to a higher res bmp because you have already lost the information

You have to go back to your infinate res metafile and sample again to the higher res bmp.

Posted: Sun Mar 29, 2009 12:47 am
by 10546565
Think of it more a a law of physics.
:-) I think you misunderstand me--I understand what you are saing.

If I am initially creating a bitmap from a TChart, why can't I tell the bitmap to have 200 pixels per inch, or 5x the density it normally would when it is being drawn. They the image would scale better.

Ed Dressel

Posted: Sun Mar 29, 2009 12:58 am
by 10047094
You can do that, i.e. if the current size of the bitmap is 100x100 at 100DPI (I know the screen is 96, but for simplicity sake) then you can tell TChart to render itself at 200x200. The SaveToBimap method takes a rect. However, then your lines, fonts etc will all be too small. (i.e. 8 pt font on a 100x100 bitmap should be rendered as ~16pt font on a 200x200 bitmap)


When you say you want a higher DPI then, is asking for exactly what I mentioned above. A larger image and ALL the properties of all the elements on the plot increased by the same factor as the increase in DPI.

Problem is, the TChart code is probably not set up easily. If the TeeCanvas could have a .ScaleFactor property then setting fonts, pens, brushes, lines etc could be scaled up by the canvas. But its hard to do.