Сделка (удаление) с Bitmap и Steam при загрузке и изменении размера изображения на сервер VB.net - PullRequest
1 голос
/ 08 декабря 2010

Мои коды:

    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. После того, как я сгенерирую Bitmap newImage, могу ли я сохранить его непосредственно на сервере, а не сохранить в memoryStream
  2. Каким ресурсом я должен распоряжаться? Что касается шаблона MSDN iDisposable, нам нужно избавиться от неуправляемого ресурса. Как избавиться от управляемого ресурса в методе Dispose () в C #? . мне нужно задействовать finalizer в этом случае? я правильно делаю?

  3. Можно ли улучшить коды? например запись на сервер, метод изменения размера и т. д.

С уважением,

Ответы [ 2 ]

2 голосов
/ 08 декабря 2010

Все, что имеет Dispose, вы хотите вызвать Dispose, когда вы закончите.В идеале вы должны инкапсулировать эти объекты в операторы using.Оператор using вызовет Dispose для вас, когда объект выпадает из области видимости.

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

Если кратко взглянуть на код, проблема, с которой вы столкнулись, заключается в том, что если в ваших методах есть исключениеброшен, объекты не будут вызывать метод Disposed.Вы должны как минимум обернуть свой код в блок try / catch / finally и поместить метод dispose в блок finally (лучше использовать оператор using).

Финализаторы используются в ваших объектах, чтобы убедиться, что когдаони уничтожены, ничего случайно не осталось открытым (как файл).Если все, что вы делаете, - это создание объектов внутри методов (без переменных уровня класса, от которых вам нужно избавиться), то вам не нужно реализовывать Finalizer.Вы никогда не захотите реализовать пользовательский финализатор, если в этом нет необходимости, потому что это заставляет GC выполнять дополнительную работу (переводит объект на следующий уровень GC и не уничтожает его немедленно).Судя по тому, что вы написали, похоже, вам это не нужно.

0 голосов
/ 08 декабря 2010

1) Да, вы можете и, возможно, вы должны.MemoryStream - это временная область памяти, которую необходимо закрыть.

2) Все, что реализует IDisposable.Вы не звоните в финализатор, GC делает.

3) Я опубликую и обновлю это

ОБНОВЛЕНИЕ

ОК, я посмотрел иЯ думаю, вам нужно выполнить сохранение внутри метода ResizeImageFile, чтобы вы создали FileStream, используя serverPath внутри HandleImageUpload, и передали его методу ResizeImageFile и при сохранении изображения вместо * 1016.*, вы сохраняете в FileSTream.

Вы делаете Return memoryStream.GetBuffer, и я уже тестировал ранее и знаю, что это не приведет к утечке памяти, пока вы на самом деле не утилизируете MemoryStream, но лучшесделать это явно.Хотя новое решение не использует поток памяти.

...