Solved

MetaFile cropping

Posted on 2009-04-13
15
328 Views
Last Modified: 2012-05-06
I have a metafile image saved to disk.  I would like to read in this image, snag just a portion of it (the upper left corner), and write that portion back out to a new metafile.  

I tried creating a TMetafile, loading in the file and then creating a 2nd TMetafile, setting the size and copying to it.  Even if I don't "SetSize" and do a one-to-one copy, the 2nd metafile is always much larger than the original.

Am I doing something really stupid here?  Is there an easier way to do this.

Thanks Experts!
WMF1 := TMetaFile.Create;

WMF1.LoadFromFile(fn);
 

WMF2 := TMetaFile.Create;

WMF2.SetSize(Wid,Ht);
 

WMFCanvas := TMetaFileCanvas.Create(WMF2,0);

WMFCanvas.Draw(0,0,WMF1);

WMFCanvas.Free;
 

WMF2.SaveToFile(fn2);
 

WMF1.Free;

WMF2.Free;

Open in new window

0
Comment
Question by:alexiat
  • 8
  • 7
15 Comments
 
LVL 12

Expert Comment

by:Hypo
Comment Utility
Hi,
Do you mean that the file gets larger on disk, or that the actual size/dimensions of the image is changed? Because if you only see a difference in the size on disk, then that could be explained by the fact that the original wmf file can contain vector data, but when you do your copying to the second wmf, then you use Draw, which will probably result in you loosing that vector data, and the second wmf-file will only contain a raster data representation of the vector data from the first file.

You could try changing the code to use assign instead of draw, to copy the data from the first wmf, I think that will preserve the vector data. see example below

Regards
Hypo
WMF1 := TMetaFile.Create;

WMF1.LoadFromFile(fn);

 

WMF2 := TMetaFile.Create;

WMF2.Assign(WMF1);

// WMF2.SetSize(Wid,Ht); - I didn't have SetSize in my delphi version

WMF2.Width := Wid;

WMF2.Height := Ht;

 

WMF2.SaveToFile(fn2);

 

WMF1.Free;

WMF2.Free;

Open in new window

0
 
LVL 12

Expert Comment

by:Hypo
Comment Utility
Hmm... I did some testing, and it seems that the Draw-function actually does copy the vector data from the original wmf-file, so it seems like that is not the reason why the disk size of the wmf gets bigger (if now that was your issue). Anyway, Assign seems to do the trick with the disk size.

regards
Hypo
0
 

Author Comment

by:alexiat
Comment Utility
The Assign does make the file sizes the same so that helped.  However, I still have the problem with sizing.  Example: I have a metafile image that is all white space except a small section in the upper left hand corner.  I want to copy just this upper left corner to a new metafile image so that when I save it to disk there is no white space.  Does this make sense?  Maybe it isn't even doable?

Thanks.
0
 
LVL 12

Expert Comment

by:Hypo
Comment Utility
Yeah, I think I understand what you mean, can you give an example of that file? or one that is similar to what you want to acheive?

regards
Hypo
0
 

Author Comment

by:alexiat
Comment Utility
I can't upload a .wmf file but here is an example as a bmp.  Thanks.
example.zip
0
 

Author Comment

by:alexiat
Comment Utility
I forgot to mention... this is the original layout.  What I would like to get is just the image in the upper left corner without all the white space.  I can do this with a bmp and jpg but I can't figure out how to do it with a wmf.  Thanks again.
0
 
LVL 12

Expert Comment

by:Hypo
Comment Utility
I've tested some things on an old WMF that I have here that was created using report builder (i think). When I am using the Assign method, and then change the size, I get the same image, but scaled to the new size, which is wrong.
When I change the size first, and then use the draw method, I get the correctly cropped image, but I also get an extra margin on the WMF2 file, in the top left of the image, which is also wrong. I don't know why the margin is added, but I think it has something to do with some information that comes with the source file WMF1, where it is adjusted for a printer. If this is your problem with the draw method, then I think you can solve it by just adding a negative offset when you do the draw-call...

If this doesn't work, then I think I would like to see how you calculate the Wid and Ht values that you use in SetSize...

regards
Hypo
WMF1 := TMetaFile.Create;

WMF1.LoadFromFile(fn);

 

WMF2 := TMetaFile.Create;

// WMF2.SetSize(Wid,Ht);

WMF2.Width := Wid;

WMF2.Height := Ht;

 

WMFCanvas := TMetaFileCanvas.Create(WMF2,0);

// Change your offset here until it gives the correct result... 

WMFCanvas.Draw(-50,-50,WMF1);

WMFCanvas.Free;

 

WMF2.SaveToFile(fn2);

 

WMF1.Free;

WMF2.Free;

Open in new window

0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 

Author Comment

by:alexiat
Comment Utility
I can get the image cropped now but the file size is still a bit larger and on screen it displays a bit larger.  If you look at the example bmp I uploaded, the image without white space is 2.3 inches.  When I resave the bmp or jpg I am taking the 2.3 * PixelsPerInch as my width value.  I'm guessing you have to do something different with vector data?  Is there any formula that would work?  Again, thanks for your help.
0
 
LVL 12

Expert Comment

by:Hypo
Comment Utility
This is just a longshot, but You could try to use the MMWidth and MMHeight property instead of setting the size by calculating its pixels. See if it makes any difference? MMWidth and MMHeight contains the integer width and height in 0.01 mm units, instead of in pixels. (1 inch = 2.54 mm)

regards
Hypo
0
 
LVL 12

Expert Comment

by:Hypo
Comment Utility
Correction, 1 inch = 25.4 mm :)
0
 

Author Comment

by:alexiat
Comment Utility
No luck.  I think I can run with what you have given me - not perfect but something I can at least play around with.   One more question - what exactly is the purpose of saving an image as a wmf instead of, for example, a jpg?
0
 
LVL 12

Expert Comment

by:Hypo
Comment Utility
Well, one good thing with a wmf, is that it can contain vector data... such as text and shapes etc, in which you can zoom into indefinetly without distorting the image.

If you zoom in on a jpeg image, then the best resolution you will get is based on the number of pixels in the image; so when you zoom in close enough, the letters and lines becom pixelated. When you zoom into a vector image, then the curves and diagonal lines will always have smooth edges regardless of how much you zoom in, and that is a nice feature when you are printing for instance, where the printer can have a much higher resolution (1200x1200 dpi for instance) than the screen does, which gives smooth letters. You could try to print a screen dump of a word document in paint, and then compare it with printing the same document from word, and you will understand what I'm talking about... :)

regards
Hypo
0
 

Author Comment

by:alexiat
Comment Utility
So that means if my .wmf is a bit larger it doesn't matter because someone could resize the image and it would still maintain its quality?
0
 
LVL 12

Accepted Solution

by:
Hypo earned 500 total points
Comment Utility
Yeah, that's one thing that it means; but that only applies when the data added to the wmf was in vector format. i.e. drawing an image (jpg for instance) to a wmf will not translate it into vector data, but instead add it as rasterized data, where you will still be bound to the original resolution.

regards
Hypo
0
 

Author Closing Comment

by:alexiat
Comment Utility
Thanks for giving me a good starting point and a better understanding of wmf's.  I can now capture the image without white space and it is just a matter of figuring out exactly what size to use.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
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 video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

771 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now