开发者

Deal (Dispose) with Bitmap and Steam when uploading and resize image to server VB.net

开发者 https://www.devze.com 2023-01-29 17:15 出处:网络
My codes: Public Function HandleImageUpload(ByVal serverPath As String, ByVal iWidth As Integer, ByVal iHeight As Integer) As String

My codes:

    Public Function HandleImageUpload(ByVal serverPath As String, ByVal iWidth As Integer, ByVal iHeight As Integer) As String


            Dim fileStream As Stream = imageUploader1.PostedFile.InputStream
            Dim fileName As String
            Dim newSize As Size = New Size
            Dim extension As String
            Dim imageBytes As Byte()
            Dim stream As New FileStream(serverPath, FileMode.Create)

            If imageUploader1.HasFile Then

                If imageUploader1.FileBytes.Length < 4194304 Then

                    imageBytes = imageUploader1.FileBytes
    开发者_运维知识库                fileName = imageUploader1.FileName
                    extension = Path.GetExtension(fileName)

                    If extension.ToLower = ".png" Or extension.ToLower = ".bmp" _
                        Or extension.ToLower = ".gif" Or extension.ToLower = ".jpg" Then

                        newSize.Width = iWidth
                        newSize.Height = iHeight

                        imageBytes = ResizeImageFile(fileStream, newSize)

                        stream.Write(imageBytes, 0, imageBytes.Length)
                        'need dispose or hte server will keep it'
                        stream.Dispose()

                    End If
                End If
            End If   
    End Function



    Public Function ResizeImageFile(ByVal fileStream As Stream, ByVal newSize As Size) As Byte()
        Dim memoryStream As MemoryStream = New MemoryStream

        Dim oldImage As System.Drawing.Image = System.Drawing.Image.FromStream(fileStream)


        Dim newImage As Bitmap = New Bitmap(newSize.Width, newSize.Height, PixelFormat.Format24bppRgb)

        Dim canvas As Graphics = Graphics.FromImage(newImage)
        canvas.SmoothingMode = SmoothingMode.AntiAlias
        canvas.InterpolationMode = InterpolationMode.HighQualityBicubic
        canvas.PixelOffsetMode = PixelOffsetMode.HighQuality

        canvas.DrawImage(oldImage, New Rectangle(New Point(0, 0), newSize))

        'question here'
        newImage.Save(memoryStream, ImageFormat.Jpeg)

        'Dispose right?'
        oldImage.Dispose()
        canvas.Dispose()
        newImage.Dispose()

        Return memoryStream.GetBuffer
    End Function


End Class
  1. After I generate Bitmap newImage , could I save it directly to the server rather than save it in memoryStream
  2. Which resource should I dispose? regards to MSDN iDisposable pattern, we need to dispose unmanaged resource. How to dispose managed resource in Dispose() method in C#? . do I need involve finalizer in this case? am I doing right?

  3. Can the codes be improved? e.g. write to server, resize method, etc.

Regards,


Anything that has Dispose you want to call Dispose on when you are done. Ideally, you should encapsulate these objects in using statements. The using statement will call Dispose for you when the object falls out of scope.

http://msdn.microsoft.com/en-us/library/htd05whh.aspx

Briefly looking at the code, the problem you have is that if anywhere in your methods an exception is thrown, the objects won't have the Disposed method called. You should at least wrap your code in a try/catch/finally block and put the dispose method in the finally block (the using statement is a better approach).

Finalizers are used in your objects to make sure when they are destroyed, nothing is accidentally left open (like a file). If all you are doing is creating objects within methods (no class level variables you need to get rid of), then you don't need to implement a Finalizer. You never want to implement a custom Finalizer unless you need to, because it causes the GC to do extra work (promotes the object to the next level of the GC and doesn't destroy it immediately). Based on what you've posted, it looks like you don't need one.


1) Yes, you can and perhaps you should. MemoryStream is a transient memory area which needs closing.

2) Everything that implements IDisposable. You do not call finalizer, GC does.

3) I will post and update on this

UPDATE

OK, I had a look and I think you need to do the saving inside the ResizeImageFile method so that you create the FileStream using serverPath inside HandleImageUpload and pass it to the ResizeImageFile method and when you save the image, instead of MemoryStream, you save to the FileSTream.

You do Return memoryStream.GetBuffer and I have tested before and know that this will not create memory leak while you are actually not disposing the MemoryStream but it is better to do that explicitly. Although the new solution does not involve memory stream.

0

精彩评论

暂无评论...
验证码 换一张
取 消