Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

MetaFile cropping

Posted on 2009-04-13
15
Medium Priority
?
361 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
[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
  • 8
  • 7
15 Comments
 
LVL 12

Expert Comment

by:Hypo
ID: 24135808
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
ID: 24136155
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
ID: 24136748
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
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!

 
LVL 12

Expert Comment

by:Hypo
ID: 24136904
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
ID: 24137031
I can't upload a .wmf file but here is an example as a bmp.  Thanks.
example.zip
0
 

Author Comment

by:alexiat
ID: 24137056
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
ID: 24137313
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
 

Author Comment

by:alexiat
ID: 24137817
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
ID: 24137951
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
ID: 24137959
Correction, 1 inch = 25.4 mm :)
0
 

Author Comment

by:alexiat
ID: 24138251
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
ID: 24138315
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
ID: 24138436
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 1500 total points
ID: 24138530
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
ID: 31569657
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

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

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

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…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…
Suggested Courses

604 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