C# 检查文件扩展名是否为图像的好方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17736160/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 10:21:30  来源:igfitidea点击:

Good way to check if file extension is of an image or not

c#file-extensionopenfiledialogfilefilter

提问by Pedro77

I have this file types Filters:

我有这个文件类型过滤器:

    public const string Png = "PNG Portable Network Graphics (*.png)|" + "*.png";
    public const string Jpg = "JPEG File Interchange Format (*.jpg *.jpeg *jfif)|" + "*.jpg;*.jpeg;*.jfif";
    public const string Bmp = "BMP Windows Bitmap (*.bmp)|" + "*.bmp";
    public const string Tif = "TIF Tagged Imaged File Format (*.tif *.tiff)|" + "*.tif;*.tiff";
    public const string Gif = "GIF Graphics Interchange Format (*.gif)|" + "*.gif";
    public const string AllImages = "Image file|" + "*.png; *.jpg; *.jpeg; *.jfif; *.bmp;*.tif; *.tiff; *.gif";
    public const string AllFiles = "All files (*.*)" + "|*.*";

    static FilesFilters()
    {
        imagesTypes = new List<string>();
        imagesTypes.Add(Png);
        imagesTypes.Add(Jpg);
        imagesTypes.Add(Bmp);
        imagesTypes.Add(Tif);
        imagesTypes.Add(Gif);
   }

OBS: Is there any default filters in .NET or a free library for that?

OBS:在 .NET 或免费库中是否有任何默认过滤器?

I need a static method that checks if a string is an image or not.How would you solve this?

我需要一个静态方法来检查字符串是否是图像。你会如何解决这个问题?

    //ext == Path.GetExtension(yourpath)
    public static bool IsImageExtension(string ext)
    {
        return (ext == ".bmp" || .... etc etc...)
    }

Solution using Jeroen Vannevel EndsWith. I think it is ok.

使用 Jeroen Vannevel EndsWith 的解决方案。我觉得没关系。

    public static bool IsImageExtension(string ext)
    {
        return imagesTypes.Contains(ext);
    }

采纳答案by Jeroen Vannevel

You could use .endsWith(ext). It's not a very secure method though: I could rename 'bla.jpg' to 'bla.png' and it would still be a jpg file.

你可以使用.endsWith(ext). 不过,这不是一个非常安全的方法:我可以将“bla.jpg”重命名为“bla.png”,它仍然是一个 jpg 文件。

public static bool HasImageExtension(this string source){
 return (source.EndsWith(".png") || source.EndsWith(".jpg"));
}

Thisprovides a more secure solution:

提供了更安全的解决方案:

string InputSource = "mypic.png";
System.Drawing.Image imgInput = System.Drawing.Image.FromFile(InputSource);
Graphics gInput = Graphics.fromimage(imgInput);
Imaging.ImageFormat thisFormat = imgInput.rawformat;

回答by Alejandro

An option would be to have a list of all possible valid image extensions, then that method would only check if the supplied extension is within that collection:

一个选项是列出所有可能的有效图像扩展名,然后该方法将只检查提供的扩展名是否在该集合中:

private static readonly HashSet<string> validExtensions = new HashSet<string>()
{
    "png",
    "jpg",
    "bmp"
    // Other possible extensions
};

Then in the validation you just check against that:

然后在验证中,您只需检查:

public static bool IsImageExtension(string ext)
{
    return validExtensions.Contains(ext);
}

回答by nathanchere

private static readonly string[] _validExtensions = {"jpg","bmp","gif","png"}; //  etc

public static bool IsImageExtension(string ext)
{
    return _validExtensions.Contains(ext.ToLower());
}

If you want to be able to make the list configurable at runtime without recompiling, add something like:

如果您希望能够在运行时无需重新编译即可配置列表,请添加以下内容:

private static string[] _validExtensions;

private static string[] ValidExtensions()
{
    if(_validExtensions==null)
    { 
        // load from app.config, text file, DB, wherever
    }
    return _validExtensions
}

public static bool IsImageExtension(string ext)
{
    return ValidExtensions().Contains(ext.ToLower());
}

回答by Olivier Jacot-Descombes

This method automatically creates a filter for the OpenFileDialog. It uses the informations of the image decoders supported by Windows. It also adds information of "unknown" image formats (see defaultcase of the switchstatement).

此方法会自动为OpenFileDialog. 它使用 Windows 支持的图像解码器的信息。它还增加了“未知”图像格式(见信息default的情况下switch语句)。

private static string SupportedImageDecodersFilter()
{
    ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();

    string allExtensions = encoders
        .Select(enc => enc.FilenameExtension)
        .Aggregate((current, next) => current + ";" + next)
        .ToLowerInvariant();
    var sb = new StringBuilder(500)
        .AppendFormat("Image files  ({0})|{1}", allExtensions.Replace(";", ", "),
                      allExtensions);
    foreach (ImageCodecInfo encoder in encoders) {
        string ext = encoder.FilenameExtension.ToLowerInvariant();
        // ext = "*.bmp;*.dib;*.rle"           descr = BMP
        // ext = "*.jpg;*.jpeg;*.jpe;*.jfif"   descr = JPEG
        // ext = "*.gif"                       descr = GIF
        // ext = "*.tif;*.tiff"                descr = TIFF
        // ext = "*.png"                       descr = PNG

        string caption;
        switch (encoder.FormatDescription) {
            case "BMP":
                caption = "Windows Bitmap";
                break;
            case "JPEG":
                caption = "JPEG file";
                break;
            case "GIF":
                caption = "Graphics Interchange Format";
                break;
            case "TIFF":
                caption = "Tagged Image File Format";
                break;
            case "PNG":
                caption = "Portable Network Graphics";
                break;
            default:
                caption = encoder.FormatDescription;
                break;
        }
        sb.AppendFormat("|{0}  ({1})|{2}", caption, ext.Replace(";", ", "), ext);
    }
    return sb.ToString();
}

Use it like this:

像这样使用它:

var dlg = new OpenFileDialog {
    Filter = SupportedImageDecodersFilter(),
    Multiselect = false,
    Title = "Choose Image"
};


The code above (slightly modified) can be used to find available image file extensions. In order to test if a given file extension denotes an image, I would put the valid extension in a HashSet. HashSets have an
O(1) access time! Make sure to choose a case insensitive string comparer. Since the file extensions do not contain accented or non Latin letters, the culture can safely be ignored. Therefore I use an ordinal string comparison.

上面的代码(稍作修改)可用于查找可用的图像文件扩展名。为了测试给定的文件扩展名是否表示图像,我会将有效的扩展名放在HashSet. HashSet 的
访问时间为O(1)!确保选择不区分大小写的字符串比较器。由于文件扩展名不包含重音或非拉丁字母,因此可以安全地忽略区域性。因此我使用序数字符串比较。

var imageExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
imageExtensions.Add(".png");
imageExtensions.Add(".bmp");
...

And test if a filename is an image:

并测试文件名是否为图像:

string extension = Path.GetExtension(filename);
bool isImage = imageExtensions.Contains(extension);

回答by Blechdose

I just had to do something similiar. Here is my solution:

我只需要做一些类似的事情。这是我的解决方案:

    private bool IsImage(string fileExtension)
    {
        return GetImageFileExtensions().Contains(fileExtension.ToLower()));
    }

    private static List<string> GetImageFileExtensions()
    {
        return ImageCodecInfo.GetImageEncoders()
                             .Select(c => c.FilenameExtension)
                             .SelectMany(e => e.Split(';'))
                             .Select(e => e.Replace("*", "").ToLower())
                             .ToList();            
    }