Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Windows Forms / Drawing / October 2005

Tip: Looking for answers? Try searching our database.

Image FromStream GDI+ Error with PictureBox

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Matthew - 27 Oct 2005 03:32 GMT
Howdy All,

I have an object model that stores images for use in a graphics
application. Rather than reading the images and keeping them in memory,
which has a HUGE footprint, I instead read the file into an array of
bytes, convert the array of bytes into a memory stream, then use the
Image.FromStream method to create the image. When I am done with that
image, I dispose of the image object, but keep the memory stream open
so it is quick to access next time. This sort of works and has a much
smaller footprint. However, whenever I try to display the image in a
picture box, I get the following error:

A generic GDI+ error occurred.
Invalid parameter used.

System.ArgumentException: Invalid parameter used.
  at System.Drawing.Image.get_Width()
  at System.Drawing.Image.get_Size()
  at System.Windows.Forms.PictureBox.get_ImageRectangle()
  at System.Windows.Forms.PictureBox.OnPaint(PaintEventArgs pe)
  at
System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e,
Int16 layer, Boolean disposeEventArgs)
  at System.Windows.Forms.Control.WmPaint(Message& m)
  at System.Windows.Forms.Control.WndProc(Message& m)
  at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
  at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
  at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32
msg, IntPtr wparam, IntPtr lparam)

The code that creates the memory stream and image from the stream is as
follows:

    Public Sub LoadImageStream()
        If m_ImageStream Is Nothing Then
            If m_Path.Length > 0 AndAlso System.IO.File.Exists(m_Path) Then
                SyncLock m_ImageLockObject
                    Dim fs As New System.IO.FileStream(m_Path, IO.FileMode.Open,
IO.FileAccess.Read, IO.FileShare.Read)
                    Dim arr(CInt(fs.Length - 1)) As Byte
                    fs.Read(arr, 0, CInt(fs.Length))
                    fs.Close()
                    m_ImageStream = New System.IO.MemoryStream(arr)
                End SyncLock
            End If
        End If
    End Sub

    Public ReadOnly Property Image() As System.Drawing.Bitmap
        Get
            If m_ImageStream Is Nothing Then
                LoadImageStream()
                DisposeImage()
            End If
            If m_Image Is Nothing AndAlso Not m_ImageStream Is Nothing Then
                m_Image = CType(System.Drawing.Bitmap.FromStream(m_ImageStream,
True), System.Drawing.Bitmap)
            End If
            Return m_Image
        End Get
    End Property

The image loads from the stream with no problem. But, when I try to
display the image in the picture box, I get the error.

I have seen tons of posts related to this. But, I have yet to find a
solution to the problem.

Does anyone have a solution, or is there some better method of caching
these images in memory?

Thanks,
Matthew Roberts

mroberts_hm<at>hotmail<dot>com
matthewroberts<at>srcp<dot>com
Michael Phillips, Jr. - 27 Oct 2005 15:43 GMT
When you create a bitmap from a stream,
The bitmap takes control of the stream and the
stream must remain open for the life of the bitmap.

This is a GDI+ requirement.

When you dispose of the bitmap, the stream is invalid and must
be recreated when you create another bitmap.

> Howdy All,
>
[quoted text clipped - 72 lines]
> mroberts_hm<at>hotmail<dot>com
> matthewroberts<at>srcp<dot>com
Matthew - 27 Oct 2005 16:23 GMT
The stream is remaining open. However, I was unaware that the memory
stream becomes "currupt" once the bitmap is disposed. However, in this
case, I am simply trying to display one image without disposing of
either, and I still get the error. I have even tried using "FromFile",
and it will throw the error once the image tries to draw on the
PictureBox. If, however, I clone the bitmap and try to display the
clone, all is well.

My question then would be, if the methods I am using to cache images
are not working (by caching the file streams which are small, rather
than caching the entire image which is large once decompressed), how
can I cache the images in a small footprint manner so that I do not
have to retrieve them from the file system every time I want to display
them. I need speed when switching from one image to another, so reading
from the file system is not a solution. I thought by having the file
streams cached in memory, I would work it out, but obviously this is
causing problems in GDI+.

The even stranger thing is, I have this same caching technique in
another object model that we use in production. It works 99% of the
time, but then gives that error sometimes when it tries to paint. I
created a workaround by recreating the image controls whenever this
happens, but it is a hack.

So, what would you recommend to cache images in a small footprint for
fast display?

Thanks,
Matthew
Michael Phillips, Jr. - 27 Oct 2005 19:56 GMT
Each image that you create owns the stream
until you dispose of the image.

You can not write to a stream that was opened for reading
for any image.

You can still cache your uncompressed images.

> m_ImageStream = New System.IO.MemoryStream(arr)

You can create an array of bytes that hold uncompressed
images.  Do the file IO once to fill the array with your
uncompressed images.

Just create a new Stream from the same cached byte array
every time you need to display a different image.

The cached byte array remains compressed until you associate
it with a stream for display purposes.

> The stream is remaining open. However, I was unaware that the memory
> stream becomes "currupt" once the bitmap is disposed. However, in this
[quoted text clipped - 25 lines]
> Thanks,
> Matthew

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.