从 System.Drawing.Imaging.ImageFormat 获取扩展名 (C#)

18

是否可能为任何给定的System.Drawing.Imaging.ImageFormat获取扩展名?(使用C#)

示例:

System.Drawing.Imaging.ImageFormat.Tiff -> .tif
System.Drawing.Imaging.ImageFormat.Jpeg -> .jpg
...

这可以很容易地使用查找表完成,但我想知道在 .Net 中是否有任何原生的方法。


可能是C# ImageFormat to string的重复问题。 - Bridge
5个回答

33

我现在已经找到了三种方法来做到这一点,其中最后两种方法是等效的。它们都是扩展方法,并旨在生成形式为“.foo”的扩展。

static class ImageFormatUtils
{
    //Attempt 1: Use ImageCodecInfo.GetImageEncoders
    public static string FileExtensionFromEncoder(this ImageFormat format)
    {
        try
        {
            return ImageCodecInfo.GetImageEncoders()
                    .First(x => x.FormatID == format.Guid)
                    .FilenameExtension
                    .Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
                    .First()
                    .Trim('*')
                    .ToLower();
        }
        catch (Exception)
        {
            return ".IDFK";
        }
    }

    //Attempt 2: Using ImageFormatConverter().ConvertToString()
    public static string FileExtensionFromConverter(this ImageFormat format)
    {
        return "." + new ImageFormatConverter().ConvertToString(format).ToLower();
    }

    //Attempt 3: Using ImageFormat.ToString()
    public static string FileExtensionFromToString(this ImageFormat format)
    {
        return "." + format.ToString().ToLower();
    }
}

作为扩展方法,它们可以像这样调用:

ImageFormat format = ImageFormat.Jpeg;
var filePath = "image" + format.FileExtensionFromEncoder();

生成的字符串将为:

"image.jpg"

为了比较这些新方法,我编写了一个简短的控制台应用程序:

class Program
{
    static void Main()
    {
        var formats = new[]
        {
            ImageFormat.Bmp, ImageFormat.Emf, ImageFormat.Exif, ImageFormat.Gif,
            ImageFormat.Icon, ImageFormat.Jpeg, ImageFormat.MemoryBmp, ImageFormat.Png,
            ImageFormat.Tiff, ImageFormat.Wmf
        };

        foreach (var format in formats)
        {
            Console.WriteLine("FromEncoder: '{0}', FromConverter: '{1}', FromToString: '{2}'", format.FileExtensionFromEncoder(), format.FileExtensionFromConverter(), format.FileExtensionFromToString());
        }
        Console.Read();
    }
}

运行此命令将产生以下输出:

FromEncoder: '.bmp', FromConverter: '.bmp', FromToString: '.bmp'
FromEncoder: '.IDFK', FromConverter: '.emf', FromToString: '.emf'
FromEncoder: '.IDFK', FromConverter: '.exif', FromToString: '.exif'
FromEncoder: '.gif', FromConverter: '.gif', FromToString: '.gif'
FromEncoder: '.IDFK', FromConverter: '.icon', FromToString: '.icon'
FromEncoder: '.jpg', FromConverter: '.jpeg', FromToString: '.jpeg'
FromEncoder: '.IDFK', FromConverter: '.memorybmp', FromToString: '.memorybmp'
FromEncoder: '.png', FromConverter: '.png', FromToString: '.png'
FromEncoder: '.tif', FromConverter: '.tiff', FromToString: '.tiff'
FromEncoder: '.IDFK', FromConverter: '.wmf', FromToString: '.wmf'

您可以看到原始方法在一些比较晦涩的格式上失败并产生'.IDFK',而其他方法实际上只是使用了格式的名称;ImageFormat.Jpeg,'.jpeg';ImageFormat.MemoryBmp,'.memorybmp'等等。

因此,如果原始问题想要'.tif'而不是'.tiff',那么第一种方法似乎适合您。或者也许两种方法的结合才是最理想的:

    public static string FileExtensionFromEncoder(this ImageFormat format)
    {
        try
        {
            return ImageCodecInfo.GetImageEncoders()
                    .First(x => x.FormatID == format.Guid)
                    .FilenameExtension
                    .Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
                    .First()
                    .Trim('*')
                    .ToLower();
        }
        catch (Exception)
        {
            return "." + format.ToString().ToLower();
        }
    }

1
这是一个非常好的答案...做得很棒! - farina
在土耳其,您必须这样指定文化:ToLower(new CultureInfo("en-us")),因为在土耳其,小写的GIF是gıf(带有一个ı)。 - Sinan ILYAS
1
@SinanILYAS 最好使用 CultureInfo.InvariantCulture - aepot

21

也许这就是你正在寻找的内容?

    public static string GetFilenameExtension(ImageFormat format)
    {
        return ImageCodecInfo.GetImageEncoders().FirstOrDefault(x => x.FormatID == format.Guid).FilenameExtension;
    }

在调用其属性之前,务必测试FirstOrDefault是否实际找到了任何内容 ;) - niklascp
5
扩展名之间用分号分隔。 - Hans Passant
对于 System.Drawing.Imaging.ImageFormat.Png,它返回 *.PNG 而不是 .png,正如 op 所请求的那样。 - dafie

6

Kevin Bray的回答很好。但是,我不完全满意通过这种方式捕获异常的方法,因此我稍微修改了他的解决方案...

public static string GetFileExtension(this ImageFormat imageFormat)
{
    var extension = ImageCodecInfo.GetImageEncoders()
        .Where(ie => ie.FormatID == imageFormat.Guid)
        .Select(ie => ie.FilenameExtension
            .Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
            .First()
            .Trim('*')
            .ToLower())
        .FirstOrDefault();

    return extension ?? string.Format(".{0}", imageFormat.ToString().ToLower());
}

3

在我的生产代码中,我使用以下代码:

    public static string GetExtensionFromImageFormat(ImageFormat img)
    {
        if (img.Equals(ImageFormat.Jpeg)) return ".jpg";
        else if (img.Equals(ImageFormat.Png)) return ".png";
        else if (img.Equals(ImageFormat.Gif)) return ".gif";
        else if (img.Equals(ImageFormat.Bmp)) return ".bmp";
        else if (img.Equals(ImageFormat.Tiff)) return ".tif";
        else if (img.Equals(ImageFormat.Icon)) return ".ico";
        else if (img.Equals(ImageFormat.Emf)) return ".emf";
        else if (img.Equals(ImageFormat.Wmf)) return ".wmf";
        else if (img.Equals(ImageFormat.Exif)) return ".exif";
        else if (img.Equals(ImageFormat.MemoryBmp)) return ".bmp";
        return ".unknown";
    }

3

我对 Niklas 的答案进行了一些修改,因为我正在寻找一种获取适合附加到文件名的文件扩展名的方法。我在这里发布我的解决方案,以防其他谷歌搜索者正在寻找同样的内容:

public string GetFilenameExtension(ImageFormat format)
{
    return ImageCodecInfo.GetImageEncoders()
                         .First(x => x.FormatID == format.Guid)
                         .FilenameExtension
                         .Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
                         .First()
                         .Trim('*');
}

如果您这样调用它:

var filePath = "image" + GetFilenameExtension(ImageFormat.Jpeg);

生成的字符串将是:
"image.JPG"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接