smithmrk
asked on
Memory Question
OK, I need to understand something because I'm confused!
I have this loop here that adds images to a ArrayList from Memory.
Then I loop through the ArrayList to create a Multipage TIFF File.
What I don't understand is if I close the MemoryStream after I create each image it still adds the images to the ArrayList...but when I go to read them I get an error that the Stream is closed?
This WORKS:
For icount As Int16 = 0 To 2
Dim Ticket As New Bitmap(1312, 574)
Dim ticketGraphics As Graphics = Graphics.FromImage(Ticket)
Dim MyFont As New Font("Arial", 20, FontStyle.Regular)
Dim memstrm As IO.MemoryStream = New IO.MemoryStream
ticketGraphics.DrawString( "-- Test Ticket --", MyFont, Brushes.Black, 520, 90)
ticketGraphics.DrawString( icount.ToS tring, MyFont, Brushes.Black, 520, 120)
Ticket.Save(memstrm, System.Drawing.Imaging.Ima geFormat.T iff)
MultipageImages.Add(memstr m)
memstrm.Flush()
Next
This DOES NOT WORK after I add them all to the ArrayList:
For icount As Int16 = 0 To 2
Dim Ticket As New Bitmap(1312, 574)
Dim ticketGraphics As Graphics = Graphics.FromImage(Ticket)
Dim MyFont As New Font("Arial", 20, FontStyle.Regular)
Dim memstrm As IO.MemoryStream = New IO.MemoryStream
ticketGraphics.DrawString( "-- Test Ticket --", MyFont, Brushes.Black, 520, 90)
ticketGraphics.DrawString( icount.ToS tring, MyFont, Brushes.Black, 520, 120)
Ticket.Save(memstrm, System.Drawing.Imaging.Ima geFormat.T iff)
MultipageImages.Add(memstr m)
memstrm.Flush()
memstrm.Close()
Next
Private Sub CreateMultiPage_ImageFile( )
ImageWriter = New IO.FileStream("C:\MemoryTe st.tif", FileMode.Create)
Dim saveEncoder As Encoder
Dim compressionEncoder As Encoder
Dim SaveEncodeParam As EncoderParameter
Dim EncoderParams As New EncoderParameters(1)
Dim codecInfo As ImageCodecInfo = getCodecForString("TIFF")
saveEncoder = Encoder.SaveFlag
compressionEncoder = Encoder.Compression
' Save the first page:.
SaveEncodeParam = New EncoderParameter(saveEncod er, CLng(EncoderValue.MultiFra me))
EncoderParams.Param(0) = SaveEncodeParam
Dim TicketImage As Image = Image.FromStream(DirectCas t(Multipag eImages(0) , Stream))
TicketImage.Save(ImageWrit er, codecInfo, EncoderParams)
For iCount As Int16 = 1 To MultipageImages.Count - 1
' Save the next set of pages:
SaveEncodeParam = New EncoderParameter(saveEncod er, CLng(EncoderValue.FrameDim ensionPage ))
EncoderParams.Param(0) = SaveEncodeParam
Dim NextImage As Image = Image.FromStream(DirectCas t(Multipag eImages(iC ount), Stream))
TicketImage.SaveAdd(NextIm age, EncoderParams)
Next
SaveEncodeParam = New EncoderParameter(saveEncod er, CLng(EncoderValue.Flush))
EncoderParams.Param(0) = SaveEncodeParam
TicketImage.SaveAdd(Encode rParams)
MultipageImages.Clear()
MultipageImages = Nothing
ImageWriter.Close()
ImageWriter.Dispose()
End Sub
The error occurs when trying to load the Image From the ArrayList into an Image...but it works fine if I don't close the Memory Stream after each image...why?
Just trying to manage the memory to the best to not overload it.
Thanks,
Mark
I have this loop here that adds images to a ArrayList from Memory.
Then I loop through the ArrayList to create a Multipage TIFF File.
What I don't understand is if I close the MemoryStream after I create each image it still adds the images to the ArrayList...but when I go to read them I get an error that the Stream is closed?
This WORKS:
For icount As Int16 = 0 To 2
Dim Ticket As New Bitmap(1312, 574)
Dim ticketGraphics As Graphics = Graphics.FromImage(Ticket)
Dim MyFont As New Font("Arial", 20, FontStyle.Regular)
Dim memstrm As IO.MemoryStream = New IO.MemoryStream
ticketGraphics.DrawString(
ticketGraphics.DrawString(
Ticket.Save(memstrm, System.Drawing.Imaging.Ima
MultipageImages.Add(memstr
memstrm.Flush()
Next
This DOES NOT WORK after I add them all to the ArrayList:
For icount As Int16 = 0 To 2
Dim Ticket As New Bitmap(1312, 574)
Dim ticketGraphics As Graphics = Graphics.FromImage(Ticket)
Dim MyFont As New Font("Arial", 20, FontStyle.Regular)
Dim memstrm As IO.MemoryStream = New IO.MemoryStream
ticketGraphics.DrawString(
ticketGraphics.DrawString(
Ticket.Save(memstrm, System.Drawing.Imaging.Ima
MultipageImages.Add(memstr
memstrm.Flush()
memstrm.Close()
Next
Private Sub CreateMultiPage_ImageFile(
ImageWriter = New IO.FileStream("C:\MemoryTe
Dim saveEncoder As Encoder
Dim compressionEncoder As Encoder
Dim SaveEncodeParam As EncoderParameter
Dim EncoderParams As New EncoderParameters(1)
Dim codecInfo As ImageCodecInfo = getCodecForString("TIFF")
saveEncoder = Encoder.SaveFlag
compressionEncoder = Encoder.Compression
' Save the first page:.
SaveEncodeParam = New EncoderParameter(saveEncod
EncoderParams.Param(0) = SaveEncodeParam
Dim TicketImage As Image = Image.FromStream(DirectCas
TicketImage.Save(ImageWrit
For iCount As Int16 = 1 To MultipageImages.Count - 1
' Save the next set of pages:
SaveEncodeParam = New EncoderParameter(saveEncod
EncoderParams.Param(0) = SaveEncodeParam
Dim NextImage As Image = Image.FromStream(DirectCas
TicketImage.SaveAdd(NextIm
Next
SaveEncodeParam = New EncoderParameter(saveEncod
EncoderParams.Param(0) = SaveEncodeParam
TicketImage.SaveAdd(Encode
MultipageImages.Clear()
MultipageImages = Nothing
ImageWriter.Close()
ImageWriter.Dispose()
End Sub
The error occurs when trying to load the Image From the ArrayList into an Image...but it works fine if I don't close the Memory Stream after each image...why?
Just trying to manage the memory to the best to not overload it.
Thanks,
Mark
You are just adding a reference to the original stream to the array so when you access it, it still tries to access the original memstream.
ASKER
OK, it this a good practice or should I be doing something different to use the memory resources to the best?
Thanks,
Mark
Thanks,
Mark
You can keep the images in memory as ByteArray instead of streams.
ASKER
OK...how do I convert / change my code to use a Byte Array vs. the Array List?
Thanks,
Mark
Thanks,
Mark
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
How does this look?
Imports System.IO
Imports System.Xml
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices
Public Class Form1
Private ImageWriter As IO.FileStream
Private MultipageImages As New ArrayList
Private ImageByteArray As Byte()
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
For icount As Int16 = 0 To 4
Dim Ticket As New Bitmap(1312, 574)
Dim ticketGraphics As Graphics = Graphics.FromImage(Ticket)
Dim MyFont As New Font("Arial", 20, FontStyle.Regular)
Dim memstrm As IO.MemoryStream = New IO.MemoryStream
ticketGraphics.DrawString("-- Test Ticket --", MyFont, Brushes.Black, 520, 90)
ticketGraphics.DrawString(icount.ToString, MyFont, Brushes.Black, 520, 120)
Ticket.Save(memstrm, System.Drawing.Imaging.ImageFormat.Tiff)
ImageByteArray = memstrm.ToArray
MultipageImages.Add(ImageByteArray)
memstrm.Flush()
memstrm.Close()
memstrm.Dispose()
Ticket.Dispose()
ticketGraphics.Dispose()
MyFont.Dispose()
ImageByteArray = Nothing
Next
Call CreateMultiPage_ImageFile()
MessageBox.Show("Done")
End Sub
Private Sub CreateMultiPage_ImageFile()
ImageWriter = New IO.FileStream("C:\MemoryTest.tif", FileMode.Create)
Dim saveEncoder As Encoder
Dim compressionEncoder As Encoder
Dim SaveEncodeParam As EncoderParameter
Dim EncoderParams As New EncoderParameters(1)
Dim codecInfo As ImageCodecInfo = getCodecForString("TIFF")
saveEncoder = Encoder.SaveFlag
compressionEncoder = Encoder.Compression
' Save the first page:.
SaveEncodeParam = New EncoderParameter(saveEncoder, CLng(EncoderValue.MultiFrame))
EncoderParams.Param(0) = SaveEncodeParam
ImageByteArray = MultipageImages(0)
Dim memstrm As IO.MemoryStream = New IO.MemoryStream(ImageByteArray)
Dim TicketImage As Image = Image.FromStream(memstrm)
TicketImage.Save(ImageWriter, codecInfo, EncoderParams)
memstrm.Flush()
memstrm.Close()
memstrm.Dispose()
ImageByteArray = Nothing
For iCount As Int16 = 1 To MultipageImages.Count - 1
' Save the next set of pages:
SaveEncodeParam = New EncoderParameter(saveEncoder, CLng(EncoderValue.FrameDimensionPage))
EncoderParams.Param(0) = SaveEncodeParam
ImageByteArray = MultipageImages(iCount)
memstrm = New IO.MemoryStream(ImageByteArray)
Dim NextImage As Image = Image.FromStream(memstrm)
TicketImage.SaveAdd(NextImage, EncoderParams)
memstrm.Flush()
memstrm.Close()
memstrm.Dispose()
NextImage.Dispose()
ImageByteArray = Nothing
Next
SaveEncodeParam = New EncoderParameter(saveEncoder, CLng(EncoderValue.Flush))
EncoderParams.Param(0) = SaveEncodeParam
TicketImage.SaveAdd(EncoderParams)
MultipageImages.Clear()
MultipageImages = Nothing
ImageWriter.Close()
ImageWriter.Dispose()
End Sub
Private Function getCodecForString(ByVal type As String) As ImageCodecInfo
Dim info As ImageCodecInfo() = ImageCodecInfo.GetImageEncoders()
For i As Integer = 0 To info.Length - 1
Dim EnumName As String = type.ToString()
If info(i).FormatDescription.Equals(EnumName) Then
Return info(i)
End If
Next
Return Nothing
End Function
End Class
Looks fine. Does it work?
ASKER
YES, Thank You!
I'm just trying to make my program as efficent as possible to make the best of memory and resources.
Thanks again,
Mark
I'm just trying to make my program as efficent as possible to make the best of memory and resources.
Thanks again,
Mark
ASKER
Thanks for you help!
Mark
Mark
Glad it worked :-)