How to Improve Memory Utilization when using Chart Image in Multi-Document VsPrinter
When a multiple document containing Chart images is generated in VsPrinter, a lot of memory is utilized if the heavy bitmap images are used. The expected memory usage of an application works on the following formula count :
Memory usage = Image Size X Page Count
That is, if a 4 Mb file is used to render 20 pages, 80 MB memory will be used. Similarly, for 100 pages 400 MB memory is used.
There are two ways to reduce the memory usage:
1. Use metafiles instead of bitmaps
2. Use smaller images
Option 1 is naturally better, because it preserves the image quality.
Hoever, a question arises--why can't we just use Jpeg or Gif images which are also smaller in size? This happens because Windows does not deal with compressed bitmaps. When it renders a png or jpg into a memory metafile, the bitmap is expanded first. The same happens when we try to save a bitmap file into Emf/Wmf files.
You need to create real metafiles which contain drawing commands instead of bitmaps.
To create a metafile in C1Chart8, you can use the DrawToFile() method to create WMF and EMF files. For example :
Chart2D1.DrawToFile "c:\\EnhancedMetaFile.emf", oc2dFormatEnhMetafile
On using the metafile created using the above method, the memory usage is very less compared to an application using bitmap images.
Step 1 : Creation of Metafile Image
We will use the Alamz product sample of C1Chart8 to create our bitmap and metafile images. The chartimages used in our sample will be created using the DrawToFiel() method. Take, for example, the following line of code to create an enhanced metfile:
Chart2D1.DrawToFile "c:\\ChartImage.emf", oc2dFormatEnhMetafile
Step 2 : Creation of Printdocuments
In this step we will place a VsPrinter on the form and add 2 buttons – Render Bitmap Image and Render Metafile Image.
We will use VsPrinter.DrawPicture() method to add an image to print the document. A loop is also used to create multiple documents.
The following code is used to generate the documents. The only difference between the button click events of Render Bitmap Image and Render Metaile Image is the image name used. In the following code Bitmap image name is used :
Dim x As Integer
With vp
' set up styles
.PaperBin = binAuto + &H1000&
.FontName = "Tahoma"
.FontSize = 18
.IndentLeft = 0
.SpaceAfter = "8pt"
.Styles.Add "Title", vpsContent
.FontSize = 12
.IndentLeft = "0.25in"
.Styles.Add "Normal", vpsContent
' set up page
.Header = "Display Pictures||Page %d"
.Footer = "Page %d||Display Pictures"
.PageBorder = pbTopBottom
.MarginLeft = "1.5in"
.HdrFontSize = 9
.HdrFontBold = True
' start document
.StartDoc
For x = 1 To 20
' create document
.Styles.Apply "Title"
.Paragraph = "Display Pictures"
' include a picture in main document
Dim sPicFile$
sPicFile = App.Path & "\\ChartImage.bmp"
.DrawPicture LoadPicture(sPicFile), .MarginLeft + .IndentLeft, .CurrentY
' add a little more text after the picture
.CurrentY = .Y2
.Paragraph = ""
.Paragraph = "This appears after the picture."
.NewPage
Next x
.EndDoc
Step 3 : Generate Project Exe
Go to File and select Make Project1.exe to create an executable file. After the executable is created , run the file.
The memory utilization of the application is around 5 MB. Click on 'Render Bitmap Image'. The memory usage will shoot up to 23 MB.
Now, close the Project1.exe and rerun it. Again, the Memory usage is 5 MB. When the 'Render Metafile Image' button is clicked and metafiles are added to the VsPrinter document, the memory usage is around 9 MB.