• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 615
  • Last Modified:

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.

'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()

Open in new window

0
ericvbnet
Asked:
ericvbnet
  • 10
  • 5
  • 4
  • +1
1 Solution
 
Anurag ThakurCommented:
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
0
 
aikimarkCommented:
>>'  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.
0
 
ericvbnetAuthor Commented:
I generate each image file in sequence so I don't have the option of using multiple threads.
0
Industry Leaders: 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!

 
ericvbnetAuthor Commented:
If the images are not made larger before conversion, then when the png is resized larger, it becomes blurry.
0
 
aikimarkCommented:
We can address resizing issues after we address this performance problem.

I want to know the effect of the resizing on performance.  If you have 107 graph images in your EMF file, it probably isn't small.  The 4x4 increase in the height and width dimensions means that you are increasing the bitmap and png image sizes 16 fold.  

You might be brushing up against your physical memory limits, since you will have all three image types in memory during your conversion.

=============
We will also need to explore other methods of transferring the bitmap data to png, such as using PngBitmapEncoder().
0
 
ericvbnetAuthor Commented:
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  
0
 
ericvbnetAuthor Commented:
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.
0
 
CodeCruiserCommented:
> The process (with N = 107 in my example) goes
>Create EMF file

Do you have  control on the Create EMF Files process?
0
 
ericvbnetAuthor Commented:
Yes. They are graphs that are also created in the same program.
0
 
CodeCruiserCommented:
Can you not change size of those?
0
 
ericvbnetAuthor Commented:
But they are based on the incoming numbers, so each graph is different.
0
 
ericvbnetAuthor Commented:
I'm not sure I understand what you mean by changing the size.
0
 
CodeCruiserCommented:
Can you show the code that's generating these EMF files?
0
 
aikimarkCommented:
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.
0
 
ericvbnetAuthor Commented:
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

Open in new window

0
 
CodeCruiserCommented:
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

0
 
ericvbnetAuthor Commented:
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.
0
 
CodeCruiserCommented:
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.
0
 
ericvbnetAuthor Commented:
We are still in 3.5. Thank you for your input.
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.

  • 10
  • 5
  • 4
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now