Link to home
Start Free TrialLog in
Avatar of alexiat
alexiat

asked on

MetaFile cropping

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

Avatar of Hypo
Hypo
Flag of Sweden image

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

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
Avatar of alexiat
alexiat

ASKER

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.
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
Avatar of alexiat

ASKER

I can't upload a .wmf file but here is an example as a bmp.  Thanks.
example.zip
Avatar of alexiat

ASKER

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.
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

Avatar of alexiat

ASKER

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.
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
Correction, 1 inch = 25.4 mm :)
Avatar of alexiat

ASKER

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?
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
Avatar of alexiat

ASKER

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?
ASKER CERTIFIED SOLUTION
Avatar of Hypo
Hypo
Flag of Sweden image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of alexiat

ASKER

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.