ExternalException在不同的文件夹中保存具有相同名称的System.Drawing.Bitmap

时间:2014-02-01 21:02:49

标签: vb.net debugging exception bitmap

我正在使用自动图像裁剪器,每当我将裁剪后的图像保存为任意名称(例如:C:\test.jpg - > C:\blargh.jpg)时,它工作正常,但是当我保存它时在不同的文件夹中使用相同的文件名(例如:C:\test.jpg - > C:\tmp\test.jpg),会抛出System.Runtime.InteropServices.ExternalException。 MSDN说当“图像以错误的图像格式保存 - 或者 - 图像保存到它创建的同一文件中时出现了这样的错误。”

我的猜测是VB试图通过检查save-filename的open-filename来实现智能,但忽略了文件夹。我怎样才能解决这个烦人的行为?这是我目前的代码:

    Dim CropImage = New Bitmap(CropRect.Width, CropRect.Height)
        'save in "output" folder
        Dim tmp() As String 'directory, filename
        Dim strIsolatedFolder As String
        Dim intUBound As Integer
        Dim i As Integer
        'split the sting at all the backslashes
        tmp = Split(filename, "\")
        'find out how many pieces there are
        intUBound = UBound(tmp)
        'I want all but the last piece
        strIsolatedFolder = ""
        For i As Integer = 0 To intUBound - 1
            If i = 0 Then
                strIsolatedFolder = tmp(i)
            Else
                're-add all backslashes except the very last one!
                strIsolatedFolder = strIsolatedFolder & "\" & tmp(i)
            End If
        Next i
        ' strIsolatedFolder will be the part before the last '\' (the directory)
        ' tmp.Last will be the part after (the filename, including extension)
        Dim saveAs As String = strIsolatedFolder & "\output\" & System.IO.Path.ChangeExtension(tmp.Last, strExtension) 'save in folder "output"
    Using grp = Graphics.FromImage(CropImage)
        grp.DrawImage(bmpSource, New Rectangle(0, 0, CropRect.Width, CropRect.Height), CropRect, GraphicsUnit.Pixel)
    Select Case strExtension
            Case "jpg"
                CropImage.Save(saveAs, System.Drawing.Imaging.ImageFormat.Jpeg)
            Case "bmp"
                CropImage.Save(saveAs, System.Drawing.Imaging.ImageFormat.Bmp)
            Case "gif"
                CropImage.Save(saveAs, System.Drawing.Imaging.ImageFormat.Gif)
        End Select
    End Using

假设:

  1. filename实际上是可加载VB的图像的文件名

  2. strExtension总是“jpg”,“bmp”或“gif”

  3. bmpSourceSystem.Drawing.Bitmap类型的私有成员,其中包含有效图片

  4. CropRectRectangle,其界限为bmpSource

  5. 当输入和输出文件扩展名相同时,错误仍然存​​在

  6. 添加文件夹时没有逻辑错误。使用断点,我发现saveAs的最终值是完美构造的。示例:C:\Users\Snoopy\Documents\test.bmp将变为C:\Users\Snoopy\Documents\output\test.jpg,假设strExtension为“jpg”

  7. 我的代码中是否有任何修复,或者这真的是VB中的错误?

2 个答案:

答案 0 :(得分:1)

  

图像已保存到从

创建的同一文件中

是的,这是获得此异常的一个非常常见的原因。但不是唯一的。当任何原因导致Image.Save()无法写入文件时,您也会得到它。异常消息很臭,你必须找出原因。常见错误是没有对目录的写访问权限,使用与子目录相同的文件名保存,保存到不存在的目录。这样的场景:

  • 你开始编写代码,保存工作正常
  • 您启动了一个图像查看器,看看结果如何
  • 图片查看器将 lock 放在文件
  • 您对代码进行了一些更正,并使用相同的文件名重新编写程序
  • KABOOM。图像查看器仍然锁定了文件。你必须关闭观众。

如果您完全不知道,那么您可以从SysInternals的Process Monitor获取错误代码。你会看到你的程序试图打开文件而失败了。

另请注意Save()调用中的错误,您始终以PNG格式保存图像,因为您没有使用ImageFormat参数的重载。所以你的.jpg文件实际上包含一个png。

答案 1 :(得分:0)

知道了!显然,Bitmap.Save 不会创建一个文件夹,如果我告诉它保存在一个不存在的文件夹中,就像我假设的那样。一旦我添加了

If (Not System.IO.Directory.Exists(strIsolatedDirectory & "\output")) Then System.IO.Directory.CreateDirectory(strIsolatedDirectory & "\output")

在致电Save之前,代码有效。