Solved

Metafile scaling - how do I get real size?

Posted on 1997-10-22
11
1,548 Views
Last Modified: 2008-03-10
Here's a weird one.  In VB5, when you import and print a WMF, the thing prints original size (of course you'd have to use VB which takes the fun away.<g>)

In Delphi (2), the size is shrunk by a huge amount.  It looks like it is taking the pixel resolution?  I can stretch it to fit the page, but I want to keep the original's size so I can write on the graphic form.


var
   Wmf1: TMetaFile;
   r: TRect;
begin
     Wmf1 := TMetaFile.Create;
     Wmf1.LoadFromFile('D:\BACKUP\DELPHI\FormPrint\7501.wmf');
     // Wmf1.Inch := 1440;
     // In Pixels for some reason.  96 pixels per inch
     if PrintDialog1.Execute then begin;
        Printer.BeginDoc;                               { begin to send print job to printer }
        Printer.NewPage;
        r:=Printer.Canvas.ClipRect;
        Printer.Canvas.Draw(0,0,Wmf1);
        // Printer.Canvas.StretchDraw(Printer.Canvas.ClipRect, Wmf1);
        Printer.EndDoc;
0
Comment
Question by:sfb
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
  • 2
11 Comments
 
LVL 3

Expert Comment

by:mirek071497
ID: 1348590
Do you try Wmf1.Width and Height after Loading from file ?
0
 

Author Comment

by:sfb
ID: 1348591
Yes Mirek.  I tried looking at it through debug - I don't have the exact value with me, but it was a height of around 900 to just over 1000.  At 96 pixels per inch, it appears as though the WMF is about right for screen display.  Roughly 6.5 times smaller than what is needed for a 600dpi printer.

0
 
LVL 3

Expert Comment

by:mirek071497
ID: 1348592
In Delphi2 and 3 You can Use GetEnhMetafileHeader the last value in this header is szlMillimeters which specifies the resolution of the reference device, in millimeters The previus value szlDevice specifies the resolution of the reference device, in pixels.

This can help you ?


0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 4

Expert Comment

by:StevenB
ID: 1348593
 StretchDrawing a Metafile like this will result in a small image because as you say the pixel resolution of the printer is very high. The solution I use is to take the X and Y resolutions of the printer and then calculate the actual size of the rectangle that the metafile should be drawn into in printer units. The pixel units in a metafile correspond to 1/100 mm so the conversion is very simple.
  I'm in a hurry right now so I'll leave this as an answer. If you think I'm on the right track then leave a message, and I'll post up the code to do all this.

  Steven.

0
 

Author Comment

by:sfb
ID: 1348594
Hi Steven,

I think you're on the right track, but I want to clarify a few points.  1) The stretchdraw is commented out - the 'straight' draw produces the small image.  2) I don't want to stretch the image to fit available space ... I want to convert it back to original size.

The metafile is a form - complete with text in certain point sizes.  I want to fill in the blanks within my print routine - so I need the metafile in it's exact size and proportion to hit the blank spaces correctly.

I figured there was an easy way to get the printer resolution and perform a stretch based on the conversion factor of the original wmf.

If that's what you have, post away!!!

Thanks,

Scott
0
 
LVL 4

Expert Comment

by:StevenB
ID: 1348595
 It is pretty simple, I'll post it on Monday, cause I've got some examples at work.

Steven.
0
 
LVL 4

Expert Comment

by:StevenB
ID: 1348596
Hi Scott,

  Try this:

  Make a new application, add a button and link it to this method (you'll have to add Printers to the Uses also):


procedure TForm1.Button1Click(Sender: TObject);
var
  ADevice,ADriver,APort : ARRAY [0..255] of Char;
  DeviceHandle : THandle;
  DevMode : PDeviceMode;
  DPIx,DPIy : Integer;
  XSc,YSc : Double;
  XSize,YSize : Integer;
  AMetaMMWidth,AMetaMMHeight : Integer;
  Printer : TPrinter;
  AMetafile : TMetafile;
  AnOpenDialog : TOpenDialog;
begin
  try
    AMetaFile := TMetafile.Create;
    Printer := TPrinter.Create;
    AnOpenDialog := TOpenDialog.Create(Self);
    If AnOpenDialog.Execute then begin

      Printer.GetPrinter(ADevice,ADriver,APort,DeviceHandle); // Initialise everything
      AMetafile.LoadFromFile(AnOpenDialog.FileName);

      If DeviceHandle = 0 then begin
        Printer.PrinterIndex := Printer.PrinterIndex;
        Printer.GetPrinter(ADevice,ADriver,APort,DeviceHandle);
      end;
      If DeviceHandle = 0 then
        Raise Exception.Create('Could Not Initialize Printer')
      else
        DevMode := GlobalLock(DeviceHandle);

      with DevMode^ do begin
        dmFields := dmFields or DM_PRINTQUALITY; // Calculate scaling in dots per inch
        DPIx := dmPrintQuality;
        dmFields := dmFields or DM_YRESOLUTION;
        DPIy := dmYResolution;
      end;

      XSc := DPIx/2540; // Convert to dots per hundredth of mm
      YSc := DPIy/2540;

      AMetaMMWidth := round(AMetaFile.Width/(Screen.PixelsPerInch/2540)); // Calculate size of metafile in 100ths mm
      AMetaMMHeight := round(AMetaFile.Width/(Screen.PixelsPerInch/2540));
      {Using AMetafile.MMWidth should have the same effect, however it seems to screw up too often}

      XSize := round(AMetaMMWidth*XSc); // Calculate sizes in printer units
      YSize := round(AMetaMMHeight*YSc);


      Printer.BeginDoc; // draw to the Printer Canvas
      try
        Printer.Canvas.StretchDraw(Rect(0,0,XSize,YSize),AMetaFile);
      finally
        Printer.EndDoc;
      end;
    end;
  finally
    Printer.Free;
    AMetaFile.Free;
    AnOpenDialog.Free;
  end;

end;



  Hopefully this should do what you're after. If it does then the code should be pretty obvious to translate to your application. If you've any more questions then fire away.

  Steven.
0
 
LVL 4

Expert Comment

by:StevenB
ID: 1348597
 I assure you that this code was indented with much more skill prior to pressing the submit button.

  Steven.
0
 
LVL 4

Accepted Solution

by:
StevenB earned 50 total points
ID: 1348598
 Hello Scott,

  Are you still out there? Perhaps you'll notice an answer.

  Steven.
0
 

Author Comment

by:sfb
ID: 1348599
Sorry for the delay.  I put the code in and ran it as is - I kept getting GPF type errors, and there was a slight problem because the height calculation was using AMetaFile.Width.

All the guts are there though!

Thanks,

Scott
0
 
LVL 4

Expert Comment

by:StevenB
ID: 1348600
 Oops, your right. Sorry about that, That'll teach me to only test the thing on square images. Have the faults stopped? What was causing them?

  Steven.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
This is a high-level webinar that covers the history of enterprise open source database use. It addresses both the advantages companies see in using open source database technologies, as well as the fears and reservations they might have. In this…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…

687 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question