ericvbnet
asked on
Draw PNG files from EMF files faster
Hello Experts, I use the code below to convert my EMF files to PNG files for many graphs at a time. Two of the steps are very slow: memoryGraphics.DrawImage and memoryBitmap.Save
I am asking for suggestions on how to speed these two steps up considerably, or an alternative faster way to generate the .png files from the EMF files.
I am asking for suggestions on how to speed these two steps up considerably, or an alternative faster way to generate the .png files from the EMF files.
'NewImage is the path to my EMF file
Dim imgMeta As New Metafile(NewImage)
Dim myWidth As Integer
Dim myHeight As Integer
myWidth = imgMeta.Width
myHeight = imgMeta.Height
' We want a high quality .png file.
' Let's quadruple the height and width.
myWidth = myWidth * 4
myHeight = myHeight * 4
Dim memoryBitmap As Bitmap
memoryBitmap = New Bitmap(myWidth, myHeight) 'adds 4 seconds for 107 graphs (14 seconds to 18 seconds)
Dim memoryGraphics As Graphics
memoryGraphics = Graphics.FromImage(memoryBitmap)
' Draw the Metafile to memory
memoryGraphics.DrawImage(imgMeta, 0, 0, myWidth, myHeight) 'adds 20 seconds for 107 graphs (18 to 38)
memoryBitmap.Save(GloTempPath & "\pngversion.png", ImageFormat.Png) 'add 30 more seconds (38 to 68) 68 is total time
imgMeta.Dispose()
>>' We want a high quality .png file.
>>' Let's quadruple the height and width.
Larger size does not equate to higher quality
Please do a performance test and do this conversion without increasing the image size.
>>' Let's quadruple the height and width.
Larger size does not equate to higher quality
Please do a performance test and do this conversion without increasing the image size.
ASKER
I generate each image file in sequence so I don't have the option of using multiple threads.
ASKER
If the images are not made larger before conversion, then when the png is resized larger, it becomes blurry.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
To clarify, there are 107 EMF files. The process (with N = 107 in my example) goes
For i = 1 to N
Run some code
Create EMF file
Convert EMF file for 3rd party software that won't use EMFs
Next
For i = 1 to N
Run some code
Create EMF file
Convert EMF file for 3rd party software that won't use EMFs
Next
ASKER
aikimark, you were absolutely right. If I don't do the 4x4 increase, the time goes from 54 seconds down to 3 seconds. The one drawback is I now have an image that is fuzzy when it is resized larger.
> The process (with N = 107 in my example) goes
>Create EMF file
Do you have control on the Create EMF Files process?
>Create EMF file
Do you have control on the Create EMF Files process?
ASKER
Yes. They are graphs that are also created in the same program.
Can you not change size of those?
ASKER
But they are based on the incoming numbers, so each graph is different.
ASKER
I'm not sure I understand what you mean by changing the size.
Can you show the code that's generating these EMF files?
I like where you're going with this CC. In addition to the source program, we might also consider preprocessing the EMF file, adjusting the size parameters before bringing it into the conversion process.
ASKER
There is a lot of code for creating the individual lines and symbols so I've just left the shell to give you an idea.
Public Function GetMetaFile(ByVal FileName As String) As Metafile
Dim G As Graphics = MetaDisplayFrm.CreateGraphics()
Dim ipHdc As IntPtr = G.GetHdc()
Dim MF As Metafile
MF = New Metafile(FileName, ipHdc)
G.ReleaseHdc(ipHdc)
G.Dispose()
Return MF
End Function
Using MF As Metafile = GetMetaFile(H.MFName)
If IsNothing(MF) Then
Exit Sub
End If
Using G As Graphics = Graphics.FromImage(MF)
G.SmoothingMode = SmoothingMode.AntiAlias
G.TextRenderingHint = GloTextRenderingHint
HistoReadBinParms(H.HP)
AxisOppositesInit(H.Axis(_Ax.T), H.Axis(_Ax.L))
AxisOppositesInit(H.Axis(_Ax.B), H.Axis(_Ax.R))
HistoSetAxisBoundaries(_Ax.T, H.Axis(_Ax.T))
HistoSetAxisBoundaries(_Ax.B, H.Axis(_Ax.B))
AxisBoundariesInit(_Ax.L, H.Axis(_Ax.L))
AxisBoundariesInit(_Ax.R, H.Axis(_Ax.R))
.
.
.
G.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
G.DrawLine(MyPen, PX0, PY0, PX1, PY1)
(many more lines and symbols in similar manner)
.
.
.
End Using
End Using
Hmm. Looks like a lot of drawing is going on in the EMF file. One of the constructors for Metafile class takes a rectangle as bounds. Try that
http://msdn.microsoft.com/en-us/library/2ea632z6.aspx
http://msdn.microsoft.com/en-us/library/2ea632z6.aspx
ASKER
I can't get the graph to draw properly with the rectangle. I think the difficulty might be that I don't know what the coordinates of the rectangle should be until after the drawing takes place.
You may have to live with it then? Are you using .NET 4? Then you can use Parallels or Tasks or else you can use threading.
ASKER
We are still in 3.5. Thank you for your input.
If we can't find you some decent performance, you might need to look at some other conversion routes.
http://downloadnew.org/home-hobby/other/image-convert-11228.html
http://www.ivanview.com/converter/emf-batch-converter.html
http://www.yankeedownload.com/software/abc-amber-svg-converter-imblq.html
http://www.yankeedownload.com/software/able-batch-converter-inlle.html
http://help.imageconverterplus.com/how-to-convert/emf_png.html
====================
Companion Software had a couple of (potentially) useful pages:
http://www.companionsoftware.com/Support/Resources/OtherHelpfulWebsites.aspx#Graphics%20Conversion%20Software
http://www.companionsoftware.com/Support/Resources/OtherHelpfulWebsites.aspx
http://downloadnew.org/home-hobby/other/image-convert-11228.html
http://www.ivanview.com/converter/emf-batch-converter.html
http://www.yankeedownload.com/software/abc-amber-svg-converter-imblq.html
http://www.yankeedownload.com/software/able-batch-converter-inlle.html
http://help.imageconverterplus.com/how-to-convert/emf_png.html
====================
Companion Software had a couple of (potentially) useful pages:
http://www.companionsoftware.com/Support/Resources/OtherHelpfulWebsites.aspx#Graphics%20Conversion%20Software
http://www.companionsoftware.com/Support/Resources/OtherHelpfulWebsites.aspx
in case of multiple images you can use threads to generate your images and it will expedite your process of images generation as each independent thread will be generating one image
I dont think there is much there to improve the performance as i think its a standard piece of code what you have shown in the query above