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.
'NewImage is the path to my EMF file Dim imgMeta As New Metafile(NewImage)Dim myWidth As IntegerDim myHeight As IntegermyWidth = imgMeta.WidthmyHeight = imgMeta.Height' We want a high quality .png file.' Let's quadruple the height and width.myWidth = myWidth * 4myHeight = myHeight * 4Dim memoryBitmap As BitmapmemoryBitmap = New Bitmap(myWidth, myHeight) 'adds 4 seconds for 107 graphs (14 seconds to 18 seconds)Dim memoryGraphics As GraphicsmemoryGraphics = Graphics.FromImage(memoryBitmap)' Draw the Metafile to memorymemoryGraphics.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 timeimgMeta.Dispose()
are you generating one image file or multiple image files (i am assuming multiple images)
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
aikimark
>>' 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.
ericvbnet
ASKER
I generate each image file in sequence so I don't have the option of using multiple threads.
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
ericvbnet
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.
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.
ericvbnet
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
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.
Nasir Razzaq
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.
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