将图像上传到服务器 VB.net 并调整其大小时处理(处置)位图和 Steam

发布于 2024-10-06 07:47:13 字数 2721 浏览 3 评论 0原文

我的代码:

    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 模式,我们需要处置非托管资源。 如何在 C# 中的 Dispose() 方法中处置托管资源?。在这种情况下我需要涉及 finalizer 吗?我做得对吗?

  3. 代码可以改进吗?例如写入服务器、调整大小方法等。

问候,

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,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

揽月 2024-10-13 07:47:13

完成后您想要调用 Dispose 的任何具有 Dispose 的内容。理想情况下,您应该将这些对象封装在 using 语句中。当对象超出范围时,using 语句将为您调用 Dispose。

http://msdn.microsoft.com/en-us/library/htd05whh.aspx 简单地看一下代码

,您遇到的问题是,如果方法中的任何地方抛出异常,则对象将不会调用 Dispose 方法。您至少应该将代码包装在 try/catch/finally 块中,并将 dispose 方法放在 finally 块中(using 语句是更好的方法)。

终结器在对象中使用,以确保当它们被销毁时,不会意外地留下任何打开的东西(如文件)。如果您所做的只是在方法中创建对象(不需要删除任何类级别变量),那么您不需要实现 Finalizer。除非需要,否则您永远不想实现自定义 Finalizer,因为它会导致 GC 执行额外的工作(将对象提升到 GC 的下一个级别,并且不会立即销毁它)。根据您发布的内容,看来您不需要。

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.

皇甫轩 2024-10-13 07:47:13

1) 是的,你可以,也许你应该。 MemoryStream 是一个需要关闭的临时内存区域。

2)所有实现IDisposable的东西。您不调用终结器,而是 GC 调用。

3) 我将发布并更新此

更新

好的,我看了一下,我认为您需要在 ResizeImageFile 方法中进行保存,以便创建 FileStreamHandleImageUpload 中使用 serverPath 并将其传递给 ResizeImageFile 方法,并在保存图像时,而不是 MemoryStream,您保存到FileSTream

您确实返回了 memoryStream.GetBuffer ,并且我之前已经测试过,并且知道这不会造成内存泄漏,而您实际上没有处置 MemoryStream 但最好明确地这样做。虽然新方案不涉及内存流。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文