Find image format using Bitmap object in C#

后端 未结 11 2468
半阙折子戏
半阙折子戏 2020-11-29 19:50

I am loading the binary bytes of the image file hard drive and loading it into a Bitmap object. How do i find the image type[JPEG, PNG, BMP etc] from the Bitmap object?

相关标签:
11条回答
  • 2020-11-29 20:03

    here is my code for this. You have to load the complete image or the header (first 4 bytes) to a byte array first.

    public enum ImageFormat
    {
        Bmp,
        Jpeg,
        Gif,
        Tiff,
        Png,
        Unknown
    }
    
    public static ImageFormat GetImageFormat(byte[] bytes)
    {
        // see http://www.mikekunz.com/image_file_header.html  
        var bmp    = Encoding.ASCII.GetBytes("BM");     // BMP
        var gif    = Encoding.ASCII.GetBytes("GIF");    // GIF
        var png    = new byte[] { 137, 80, 78, 71 };    // PNG
        var tiff   = new byte[] { 73, 73, 42 };         // TIFF
        var tiff2  = new byte[] { 77, 77, 42 };         // TIFF
        var jpeg   = new byte[] { 255, 216, 255, 224 }; // jpeg
        var jpeg2  = new byte[] { 255, 216, 255, 225 }; // jpeg canon
    
        if (bmp.SequenceEqual(bytes.Take(bmp.Length)))
            return ImageFormat.Bmp;
    
        if (gif.SequenceEqual(bytes.Take(gif.Length)))
            return ImageFormat.Gif;
    
        if (png.SequenceEqual(bytes.Take(png.Length)))
            return ImageFormat.Png;
    
        if (tiff.SequenceEqual(bytes.Take(tiff.Length)))
            return ImageFormat.Tiff;
    
        if (tiff2.SequenceEqual(bytes.Take(tiff2.Length)))
            return ImageFormat.Tiff;
    
        if (jpeg.SequenceEqual(bytes.Take(jpeg.Length)))
            return ImageFormat.Jpeg;
    
        if (jpeg2.SequenceEqual(bytes.Take(jpeg2.Length)))
            return ImageFormat.Jpeg;
    
        return ImageFormat.Unknown;
    }
    
    0 讨论(0)
  • 2020-11-29 20:05

    A couple of clean extension methods on type Image for determining this, based on the find by Alex above (ImageCodecInfo.GetImageDecoders()).

    This is highly optimized after the first call, as the static ImageCodecsDictionary is saved in memory (but only after it has been used once).

    public static class ImageCodecInfoX
    {
    
        private static Dictionary<Guid, ImageCodecInfoFull> _imageCodecsDictionary;
    
        public static Dictionary<Guid, ImageCodecInfoFull> ImageCodecsDictionary 
        {
            get
            {
                if (_imageCodecsDictionary == null) {
                    _imageCodecsDictionary =
                        ImageCodecInfo.GetImageDecoders()
                        .Select(i => {
                            var format = ImageFormats.Unknown;
                            switch (i.FormatDescription.ToLower()) {
                                case "jpeg": format = ImageFormats.Jpeg; break;
                                case "png": format = ImageFormats.Png; break;
                                case "icon": format = ImageFormats.Icon; break;
                                case "gif": format = ImageFormats.Gif; break;
                                case "bmp": format = ImageFormats.Bmp; break;
                                case "tiff": format = ImageFormats.Tiff; break;
                                case "emf": format = ImageFormats.Emf; break;
                                case "wmf": format = ImageFormats.Wmf; break;
                            }
                            return new ImageCodecInfoFull(i) { Format = format };
                        })
                        .ToDictionary(c => c.CodecInfo.FormatID);
                }
                return _imageCodecsDictionary;
            }
        }
    
        public static ImageCodecInfoFull CodecInfo(this Image image)
        {
            ImageCodecInfoFull codecInfo = null;
    
            if (!ImageCodecsDictionary.TryGetValue(image.RawFormat.Guid, out codecInfo))
                return null;
            return codecInfo;
        }
    
        public static ImageFormats Format(this Image image)
        {
            var codec = image.CodecInfo();
            return codec == null ? ImageFormats.Unknown : codec.Format;
        }
    }
    
    public enum ImageFormats { Jpeg, Png, Icon, Gif, Bmp, Emf, Wmf, Tiff, Unknown }
    
    /// <summary>
    /// Couples ImageCodecInfo with an ImageFormats type.
    /// </summary>
    public class ImageCodecInfoFull
    {
        public ImageCodecInfoFull(ImageCodecInfo codecInfo = null)
        {
            Format = ImageFormats.Unknown;
            CodecInfo = codecInfo;
        }
    
        public ImageCodecInfo CodecInfo { get; set; }
    
        public ImageFormats Format { get; set; }
    
    }
    
    0 讨论(0)
  • 2020-11-29 20:06

    Here is my extension method. Hope this help someone.

    public static System.Drawing.Imaging.ImageFormat GetImageFormat(this System.Drawing.Image img)
        {             
            if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg))
                return System.Drawing.Imaging.ImageFormat.Jpeg;
            if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Bmp))
                return System.Drawing.Imaging.ImageFormat.Bmp;
            if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Png))
                return System.Drawing.Imaging.ImageFormat.Png;
            if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Emf))
                return System.Drawing.Imaging.ImageFormat.Emf;
            if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Exif))
                return System.Drawing.Imaging.ImageFormat.Exif;
            if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Gif))
                return System.Drawing.Imaging.ImageFormat.Gif;
            if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Icon))
                return System.Drawing.Imaging.ImageFormat.Icon;
            if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.MemoryBmp))
                return System.Drawing.Imaging.ImageFormat.MemoryBmp;
            if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Tiff))
                return System.Drawing.Imaging.ImageFormat.Tiff;
            else
                return System.Drawing.Imaging.ImageFormat.Wmf;            
        }
    
    0 讨论(0)
  • 2020-11-29 20:06

    The simplest method was offered by Cesare Imperiali as this:

    var format = new ImageFormat(Image.FromFile(myFile).RawFormat.Guid);
    

    However, the .ToString() for a .jpg returns "[ImageFormat: b96b3cae-0728-11d3-9d7b-0000f81ef32e]" instead of "Jpeg". If that matters to you, here is my solution:

    public static class ImageFilesHelper
    {
        public static List<ImageFormat> ImageFormats =>
            typeof(ImageFormat).GetProperties(BindingFlags.Static | BindingFlags.Public)
              .Select(p => (ImageFormat)p.GetValue(null, null)).ToList();
    
        public static ImageFormat ImageFormatFromRawFormat(ImageFormat raw) =>
            ImageFormats.FirstOrDefault(f => raw.Equals(f)) ?? ImageFormat.Bmp;
    
    }
    // usage:
    var format = ImageFilesHelper.ImageFormatFromRawFormat(Image.FromFile(myFile).RawFormat);
    
    0 讨论(0)
  • 2020-11-29 20:10

    Agent CK, I liked your extension method and added a string overload, plus I reduced the code for your method:

    public static class ImageExtentions
    {
        public static ImageCodecInfo GetCodecInfo(this Image img) =>
            ImageCodecInfo.GetImageDecoders().FirstOrDefault(decoder => decoder.FormatID == img.RawFormat.Guid);
    
        // Note: this will throw an exception if "file" is not an Image file
        // quick fix is a try/catch, but there are more sophisticated methods
        public static ImageCodecInfo GetCodecInfo(this string file)
        {
            using (var img = Image.FromFile(file))
                return img.GetCodecInfo();
        }
    }
    
    // Usage:
    string file = @"C:\MyImage.tif";
    string description = $"Image format is {file.GetCodecInfo()?.FormatDescription ?? "unknown"}.";
    Console.WriteLine(description);
    
    0 讨论(0)
  • 2020-11-29 20:13

    Simply speaking you can't. The reason why is that Bitmap is a type of image in the same way that JPEG, PNG, etc are. Once you load a image into a Bitmap the image of the bitmap format. There is no way to look at a bitmap and understand the original encoding of the image (if it's even different than Bitmap).

    0 讨论(0)
提交回复
热议问题