You are not logged in.
Pages: 1
Regards,
We are using your great library in order to apply antialiasing to several vectorial shapes drawed at runtime. But when it must be shown at screen, it doesn't fit on the designed size.
I attach a simple sample to show this behaviour (you only need to add an Image1 TImage into a new form to run it)
It should show an ellipsis at 50 pixels from every screen border, but it doesn't.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;
type
TfrmMain = class(TForm)
Image1: TImage;
procedure FormResize(Sender: TObject);
private
public
procedure DrawTest;
end;
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
Uses Math, SynGdiPlus;
procedure TfrmMain.FormResize(Sender: TObject);
begin
DrawTest;
end;
procedure TfrmMain.DrawTest;
var Bmp: TBitmap;
MF: TMetaFile;
MetafileCanvas: TMetafileCanvas;
DC: HDC;
ScreenLogPixels: Integer;
begin
Gdip := TGDIPlusFull.Create('gdiplus.dll'); // Dibujamos sobre un TMetafile sobre el cual podemos hacer una llamada GDI+ a aplicar Antialiasing
MF := TMetaFile.Create;
DC := GetDC(0);
ScreenLogPixels := GetDeviceCaps(DC, LOGPIXELSY);
MF.Inch := ScreenLogPixels;
MF.Width := frmMain.Width;
MF.Height := frmMain.Height;
MetafileCanvas := TMetafileCanvas.Create(MF, DC);
MetafileCanvas.Brush.Color := clRed;
MetafileCanvas.Brush.Style := bsDiagCross;
MetafileCanvas.Ellipse(50, 50, Image1.Width - 50, Image1.Height - 50);
ReleaseDC(0, DC);
MetafileCanvas.Free;
MF.Enhanced := FALSE;
Bmp := Gdip.DrawAntiAliased(MF,100,100);
Image1.Picture.Assign(Bmp);
MF.Destroy;
Self.BringToFront;
end;
end.
Can you tell us what we are doing wrong ?
Thank you.
Offline
If you disable GDI+ rendering (by letting GdiP to be nil), the drawing is the same.
Therefore, issue is not in SynGDIPlus unit.
The problem comes from the fact that you scale your picture from the main window size, then use the Image1 Width/Height for the ellipsis size.
By the way, your code creates several memory leaks:
- Is reallocating Gdip several times (at each resize);
- The Bmp shall be freed after Assign;
- Do not call MF.Destroy but MF.Free;
- Protect your resources with try..finally blocks.
Of course, this is because it's only a demo code, but ensure that production code won't suffer from these issues!
Offline
Hello.
The problem comes from the fact that you scale your picture from the main window size, then use the Image1 Width/Height for the ellipsis size.
Thanks, but I can't understand where the problem is. I have changed the code, following your advice, but I get exactly the same result. I expect an ellipsis centered on the screen, but I get an image moved to the right, with the ellipsis cutted on the right edge.
I try to set exactly the same size for the Metafile, Image and Form. I suspect that the Metafile doesn't adjust to the indicated size, so drawing into MetafileCanvas and exporting it results creates a bitmap slightly larger than Image1 bitmap.
MF.Width := frmMain.Width;
MF.Height := frmMain.Height;
Image1.Width := frmMain.Width;
Image1.Height := frmMain.Height;
Image1.Top := 0;
Image1.Left := 0;
MetafileCanvas := TMetafileCanvas.Create(MF, DC);
MetafileCanvas.Brush.Color := clRed;
MetafileCanvas.Brush.Style := bsDiagCross;
MetafileCanvas.Ellipse(50, 50, frmMain.Width - 50, frmMain.Height - 50);
I only get the expected result at a form resolution of 1209 x 907, but I don't know what is especial about that resolution. It seems that the Metafile Canvas always draws at 1209 x 907 and cuts to the desired result, but I don't understand how or why it does that.
Thanks for your kind help.
Last edited by emarc (2012-06-08 09:28:32)
Offline
This will depend on the position of Image1.
In fact, you should set MF.Width/MF.Height to the Image1.Width/Height.
This code works as expected:
procedure TForm1.FormResize(Sender: TObject);
var Bmp: TBitmap;
MF: TMetaFile;
MetafileCanvas: TMetafileCanvas;
begin
Gdip := TGDIPlusFull.Create('gdiplus.dll');
MF := TMetaFile.Create;
MF.Width := 300;
MF.Height := 200;
MetafileCanvas := TMetafileCanvas.Create(MF, 0);
MetafileCanvas.Brush.Color := clRed;
MetafileCanvas.Brush.Style := bsDiagCross;
MetafileCanvas.Ellipse(50, 50, 300 - 50, 200 - 50);
MetafileCanvas.Free;
Bmp := Gdip.DrawAntiAliased(MF);
Image1.Picture.Assign(Bmp);
Bmp.Free;
//Image1.Picture.Assign(MF);
MF.Free;
FreeAndNil(GdiP);
end;
The error is when you call MF.Height and MF.Width in MetafileCanvas.Ellipse() parameters: it does not return the expected dimensions.
You'll have to use your own variables here.
This is an issue (a feature?) with the Windows MetaFile implementation.
You'd never rely on MF.HEight/Width, but use your own variables to compute the coordinates.
Offline
Thank you very much.
It works like a charm.
Offline
Pages: 1