tags:

views:

456

answers:

3

I got an out of memory exception in a photo editor thingy i was making in vb.net. The bitmap image is constantly changing, and I always Dispose() of it after it has been sent off to the other bitmap. Is it being stored in a temp folder and using up all my space on the computer, or what? It always bugs after about 8 bitmaps have been drawn.

How do i fix this?? This is a rather serious issue.

A: 

It doesn't sound like 8 bitmaps would be enough to flood your memory. Or are they HUGE bitmaps?

I found that most out of memory exceptions are actually not out of memory exceptions at all, rather they are somehow the result of memory corruption. (I deal with a lot of unmanaged code and PInvokes so this is a rather common thing for me.)

Are you sure you need to Dispose the images? Doesn't the garbage collector automatically dispose of bitmaps?

David Rutten
Eventually, yes. But by calling Dispose you can take control of when.
Goblyn27
I think I may have found the error, see #5: http://www.nerdydork.com/crop-an-image-bitmap-in-c-or-vbnet.html Can you help me make this work? I already made it so the bounds must be constrained by the bitmap size, yet it still bugs.
Cyclone
@Cyclone: if that's actually your problem, I'm going to laugh my fool head off. I can just see the .Net programmer saying "hmmm, I should throw an OutOfMemory exception, since the user is trying to copy something that's *outside of the Bitmap's memory".* I think an ArgumentException would have made more sense here.
MusiGenesis
Shush lol, im still kinda new to vb.net. I didnt realize what was causing the exception since I am not used to dealing with bitmaps. How can I constrain the bounds of the crop section to within the bitmap for a fact? The user can click and drag to select an area, though the lasso is only visible to the lower right as we discussed before (I will be fixing that issue shortly....)
Cyclone
@Cyclone: it's not your fault - sometimes .Net components throw a weird kind of exception. For example, loading an invalid or corrupted JPEG using Bitmap.FromFile() will also throw an OutOfMemory exception, which is a big-time WTF because it makes you think you have a memory shortage when that isn't the real problem at all.
MusiGenesis
Yah lol, they really need to rename those. I am rewriting the capture code, i figured out the issue. If the user goes outside the bounds of the image, specifically too high, it'll throw that error. Would a try/catch statement suffice for this example? I could simply make it so the bounds cannot contain any point less than (0,0)...
Cyclone
@Cyclone: I wouldn't do a try/catch for that. In your code for drawing the lasso/selection rectangle, just make sure that the rectangle is never outside the bounds of the original image, even if the mouse goes outside. This is how every drawing program I've ever used behaves (but then I still use Paint, so it might not be best to listen to me).
MusiGenesis
Ugh, more thinking for me...figuring out displacement based on the window position on the user's screen is a real hassle lol. It took a ton of guesswork to even make the lasso lol....
Cyclone
+2  A: 

Disposing has nothing to do with memory. Memory is a managed resource and disposing deals with unmanaged resources, like GDI handles. If you have a global structure like dictionary or something that you add these to and don't remove them, you could be "leaking" references and not allowing the garbage collector to find them.

In these cases it's often tempting to call GC.Collect() to try to clean them up. Know that this won't help you. If the garbage collector were able to clean up the memory, it would. Calling GC.Collect() won't change things if the object you want to collect is still rooted somewhere.


Looking at the link in your comments, this might work a little better (adapted from a comment in the link):

''# Crop a bitmap
<Extension()> _
Public Function Crop(ByVal source As Bitmap, _
       ByVal cropX As Integer, ByVal cropY As Integer, _
       ByVal cropWidth As Integer, ByVal cropHeight As Integer) As Bitmap

    ''# parameter checking/guard clauses
    If source Is Nothing Then Throw New ArgumentNullException()

    If cropX > source.Width Then Throw New InvalidArgumentException("cropX")
    If cropY > source.Height Then Throw New InvalidArgumentException("cropY")

    If cropX < 0 Then cropX = 0
    If cropY < 0 Then cropY = 0

    cropWidth = Math.Min(cropWidth, source.Width - cropX)
    cropHeight = Math.Min(cropHeight, source.Height - cropY)

    ''# Create the new bitmap and associated graphics object
    Dim bmp As New Bitmap(cropWidth, cropHeight)
    Using g As Graphics = Graphics.FromImage(bmp)
        ''# Draw the specified section of the source bitmap to the new one
        g.DrawImage(source, New Rectangle(0, 0, cropWidth, cropHeight), cropX, cropY, cropWidth, cropHeight, GraphicsUnit.Pixel)
    End Using

    ''# Return the bitmap
    Return bmp
End Function

I think your problem is elsewhere, but this code is still probably a little nicer.

Joel Coehoorn
See my comment below. I need help, what can I do to ensure it is only cropping the proper, selected area?
Cyclone
A: 

I am also using GDI32 to scroll images and I get same error after 7 images I also use GC.Collect() but the error is still same please guide me how to solve this problem thank you

khurram Shehzad
Whatever you are doing to the images, something is happening outside the bounds of the image itself, which will throw that error.
Cyclone