【问题标题】:VB .NET 2010: Save a large bitmap as file [duplicate]VB .NET 2010:将大位图另存为文件[重复]
【发布时间】:2016-06-14 11:32:38
【问题描述】:


我有一个应用程序,它创建了一个包含所有 1600 万种颜色的 Bitmap 对象。最终的位图将测量 4096 × 4096 像素。
当我尝试调用 Bitmap 的 Save() 方法时,会导致错误。
这是出现的错误消息:

GDI+ 中出现一般错误。

请在这件事上帮助我。 提前致谢!


注意:请看下面源代码的最后几行注释。我已经解释了那里的疑问。
源代码:
Public Sub CreateAllColorImage()
    Dim BMP As New Bitmap(4096, 4096) 'This BMP variable is where the image will be created.'
    Dim CurrX = 0
    Dim CurrY = 0
    Dim ExitFors As Boolean = False
    For R = 0 To 255
        For G = 0 To 255
            For B = 0 To 255
                BMP.SetPixel(CurrX, CurrY, Color.FromArgb(R, G, B))
                CurrY += 1 'Increment the Y axis to move to next pixel.'
                If CurrY > 4095 Then CurrX += 1 : CurrY = 0 'Move to next row, or increment X axis, if the last pixel on the Y axis is reached'
                If CurrX > 4095 Then ExitFors = True 'Set the variable to exit the FOR loops if the very last pixel on the whole image is reached.'
                If ExitFors Then Exit For 'Exit the FOR loop if the variable is true.'
            Next
            If ExitFors Then Exit For 'Exit the FOR loop if the variable is true.'
        Next
        If ExitFors Then Exit For 'Exit the FOR loop if the variable is true.'
    Next
    'So therefore, the final image is the BMP variable.'
    'Here, I try to save the Bitmap as a file by calling this:'
    BMP.Save("C:\TEST.BMP")
    'This is when the error occurs. I think so because of the image is too large. If so, is there any way to do anything?'
    'And by the way, I already have the rights to access the C:\ drive because I am working from an Administrator account...'
    BMP.Dispose()
    BMP = Nothing
End Sub

【问题讨论】:

  • 为了检查您是否有权限这样做,只需在同一位置保存一个非常小的BMP文件,如果不能,则表示权限问题...跨度>
  • 您的代码还有另一个隐藏的问题:您泄漏了 Bitmap 对象。要么将其构造包装在 Using 语句中,要么在 sub 结束时调用它的 Dispose 方法。更喜欢前者。
  • 超级花生,你是对的。我尝试了我的桌面,它就像一个魅力!
  • @CodyGray 嗯,我会改变它

标签: vb.net bitmap


【解决方案1】:

作为普通用户,通常无法访问根C:\ 驱动器。即使您是管理员,除非另有说明,否则您的应用程序将在正常权限下运行。

不幸的是,GDI+ 隐藏了大多数异常,因此很难知道发生了什么的确切原因,但我猜您的问题是由于不允许您的应用程序直接保存在 C:\ 驱动器中。

尝试将图像保存在您可以访问的路径中,例如C:\Users\YourUserName\Desktop

【讨论】:

  • @SuperPeanut :你的英语很好。由于您的句子是如何构建的,因此可以将您的评论解释为讽刺 - 但否则它是完全有效的。这种情况也存在于母语人士身上。 (:
  • 只是一个完全无关紧要的挑剔与我的赞成意见一致:GDI+ 不会引发异常。它从 GDI+ API 中的所有函数返回 status codes。将这些状态代码转换为异常的是围绕 GDI+ 的 .NET 包装器。但更重要的一点仍然是,GDI+ 在检测错误原因和返回正确的状态代码方面做得非常糟糕。显然AccessDenied 会更适合这里。不知道他们为什么不使用那个。
  • @sree 这是因为,正如 Visual Vincent 所暗示的,Paint 不支持位图的 32 位 alpha 通道透明度。因此,当您保存它时,它会将其保存为 24 位位图。如果您不需要位图中的透明度,您可以使用相同的格式创建它。代替Using BMP As New Bitmap(4096, 4096),明确指定格式:BMP As New Bitmap(4096, 4096, PixelFormat.Format24bppRgb)。实际上,无论如何,您都应该更喜欢使用构造函数的这种重载,因为即使对于 32 位图像,Format32bppPArgb 也比默认的 Format32bppArgb 更有效 .
  • 不同的是,PArgb 表示预乘 alpha(P = premultiplied),Argb 不是预乘。你可以在谷歌上找到很多关于它的细节,但基本上它只是存储 alpha 通道信息的另一种方式。它更快的原因(根据我见过的一些基准测试,通常是 10 倍左右)是因为它与现代视频硬件在内部存储像素数据的方式相匹配,因此不需要即时转换。跨度>
  • @Sree:再次嗨!不用担心!似乎 MS Paint 已经为其 PNG 实现了一种非常有效的压缩算法。不幸的是,GDI+ 使用的算法效率不高,我更改编码器参数的尝试没有奏效。我认为你最好的选择是找到一个第三方库来更好地为你压缩图像。
【解决方案2】:

可能是权限问题。要对其进行测试,请找到您编译的 .exe 并以管理员身份运行它。如果它有效,你就知道这是一个权限问题。

如果您因为不知道用户名而尝试将其保存到 C: 驱动器,则可以改用 SpecialDirectory

例如

My.Computer.FileSystem.SpecialDirectories.MyDocuments

将让您将其保存在用户的文档文件夹中。一般来说,保存到 C: 驱动器并不是最好的做法。

我还建议使用其他可以指定图像格式的构造函数。

例如

bitmapToSave.Save(saveLocation, Imaging.ImageFormat.Bmp)

【讨论】:

  • 嗯...这似乎有效。我试过我的桌面,它工作得非常好!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-14
  • 2012-02-24
  • 2020-12-16
相关资源
最近更新 更多