3

我有一个图像大小调整程序,它可以工作。问题是当用户在文件选择对话框中选择非图像文件时,它会崩溃。如何检查图像文件?

4

5 回答 5

7

这是0xA3 的答案的 VB.NET 等价物,因为 OP 坚持使用 VB 版本。

Function IsValidImage(filename As String) As Boolean
    Try
        Dim img As System.Drawing.Image = System.Drawing.Image.FromFile(filename)
    Catch generatedExceptionName As OutOfMemoryException
        ' Image.FromFile throws an OutOfMemoryException  
        ' if the file does not have a valid image format or 
        ' GDI+ does not support the pixel format of the file. 
        ' 
        Return False
    End Try
    Return True
End Function

您可以按如下方式使用它:

If IsValidImage("c:\path\to\your\file.ext") Then
    'do something
    '
Else
    'do something else
    '
End If

编辑:
我不建议您检查文件扩展名。任何人都可以使用扩展名保存不同的文件(例如文本文档),.jpg并诱使您的应用程序相信它是图像。

最好的方法是使用上面的函数加载图像或打开前几个字节并检查 JPEG 签名。



您可以在此处找到有关 JPEG 文件及其标题的更多信息:

于 2010-08-24T17:01:46.340 回答
5

一个非常原始的检查是简单地尝试加载图像。如果它无效,OutOfMemoryException将抛出:

static bool IsImageValid(string filename)
{
    try
    {
        System.Drawing.Image img = System.Drawing.Image.FromFile(filename);
    }
    catch (OutOfMemoryException)
    {
        // Image.FromFile throws an OutOfMemoryException 
        // if the file does not have a valid image format or
        // GDI+ does not support the pixel format of the file.
        //
        return false;
    }
    return true;
}

如果我正确理解了您的问题,您的应用程序无论如何都会加载图像。因此,简单地将加载操作包装在 try/catch 块中并不意味着任何额外的开销。对于这种方法的 VB.NET 解决方案,请检查@Alex Essilfie 的答案。

想知道为什么Image.FromFile对无效文件抛出 OOM 的人应该阅读Hans Passant对以下问题的回答:

Image.FromFile 是否为无效的图像格式抛出 OutOfMemoryException 的原因?

于 2010-08-24T15:09:29.380 回答
3

当然,您的第一道防线只是检查文件的扩展名:

Function IsImageFile(ByVal filename As String) As Boolean
    Dim ext As String = Path.GetExtension(filename).ToLowerInvariant()

    ' This supposes your program can deal only with JPG files; '
    ' you could add other extensions here as necessary. '
    Return ext = ".jpg" OrElse ext = ".jpeg"
End Function

更好的是,正如 SLC 在评论中建议的那样,设置对话框的Filter属性:

dialog.Filter = "Image files|*.jpg;*.jpeg"

这不是保证 - 理想情况下,您希望检查文件本身以验证它是图像,理论上,如果它们实际上是图像文件,您也应该能够加载具有异常扩展名的文件(也许只是要求首先是用户的确认)——但这是一个简单的开始。

于 2010-08-24T15:06:25.677 回答
2

VB 和 C# 的答案很好,但如果您打算更改或移动文件,也包含一个“陷阱”:创建的“img”对象将锁定图像文件,除非调用 dispose() 方法来释放它。见下文:

VB
    Function IsValidImage(filename As String) As Boolean
    Try
        Dim img As System.Drawing.Image = System.Drawing.Image.FromFile(filename)
        img.dispose()  ' Removes file-lock of IIS
    Catch generatedExceptionName As OutOfMemoryException
        ' Image.FromFile throws an OutOfMemoryException  
        ' if the file does not have a valid image format or 
        ' GDI+ does not support the pixel format of the file. 
        ' 
        Return False
    End Try
    Return True
End Function

C#
static bool IsImageValid(string filename)
{
    try
    {
        System.Drawing.Image img = System.Drawing.Image.FromFile(filename);
        img.dispose();   // Removes file-lock of IIS
    }
    catch (OutOfMemoryException)
    {
        // Image.FromFile throws an OutOfMemoryException 
        // if the file does not have a valid image format or
        // GDI+ does not support the pixel format of the file.
        //
        return false;
    }
    return true;
}
于 2013-04-08T21:24:25.063 回答
0

最可靠的方法是了解您需要加载的文件的签名。

例如,JPEG 具有特定的标题格式。

这样,如果您只查看扩展名,您的代码就不会那么容易被愚弄。

163 的答案应该让你在这些方面得到最大程度的帮助。

于 2010-08-24T15:13:00.370 回答