Find image format using Bitmap object in C#

C#.NetImage

C# Problem Overview


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?

Looks trivial. But, couldn't figure it out!

Is there an alternative approach?

Appreciate your response.

UPDATED CORRECT SOLUTION:

@CMS: Thanks for the correct response!

Sample code to achieve this.

using (MemoryStream imageMemStream = new MemoryStream(fileData))
{
    using (Bitmap bitmap = new Bitmap(imageMemStream))
    {
        ImageFormat imageFormat = bitmap.RawFormat;
        if (bitmap.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg))
            //It's a JPEG;
        else if (bitmap.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Png))
            //It's a PNG;
    }
}

C# Solutions


Solution 1 - C#

If you want to know the format of an image, you can load the file with the Image class, and check its RawFormat property:

using(Image img = Image.FromFile(@"C:\path\to\img.jpg"))
{
    if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg))
    {
      // ...
    }
}

Solution 2 - C#

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;            
    }

Solution 3 - C#

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 };      // jpeg

	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;

	return ImageFormat.Unknown;
}

Solution 4 - C#

of course you can. ImageFormat doesn't mean much. ImageCodecInfo has much more meaning.

red_dot.png

red_dot.png

<a href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==">
    <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="red_dot.png" title="red_dot.png"/>
</a>

code:

using System.Linq;

//...

//get image
var file_bytes = System.Convert.FromBase64String(@"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==");
var file_stream = new System.IO.MemoryStream(file_bytes);
var file_image = System.Drawing.Image.FromStream(file_stream);

//list image formats
var image_formats = typeof(System.Drawing.Imaging.ImageFormat).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static).ToList().ConvertAll(property => property.GetValue(null, null));
System.Diagnostics.Debug.WriteLine(image_formats.Count, "image_formats");
foreach(var image_format in image_formats) {
    System.Diagnostics.Debug.WriteLine(image_format, "image_formats");
}

//get image format
var file_image_format = typeof(System.Drawing.Imaging.ImageFormat).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static).ToList().ConvertAll(property => property.GetValue(null, null)).Single(image_format => image_format.Equals(file_image.RawFormat));
System.Diagnostics.Debug.WriteLine(file_image_format, "file_image_format");

//list image codecs
var image_codecs = System.Drawing.Imaging.ImageCodecInfo.GetImageDecoders().ToList();
System.Diagnostics.Debug.WriteLine(image_codecs.Count, "image_codecs");
foreach(var image_codec in image_codecs) {
    System.Diagnostics.Debug.WriteLine(image_codec.CodecName + ", mime: " + image_codec.MimeType + ", extension: " + @image_codec.FilenameExtension, "image_codecs");
}

//get image codec
var file_image_format_codec = System.Drawing.Imaging.ImageCodecInfo.GetImageDecoders().ToList().Single(image_codec => image_codec.FormatID == file_image.RawFormat.Guid);
System.Diagnostics.Debug.WriteLine(file_image_format_codec.CodecName + ", mime: " + file_image_format_codec.MimeType + ", extension: " + file_image_format_codec.FilenameExtension, "image_codecs", "file_image_format_type");

debug output:

image_formats: 10
image_formats: MemoryBMP
image_formats: Bmp
image_formats: Emf
image_formats: Wmf
image_formats: Gif
image_formats: Jpeg
image_formats: Png
image_formats: Tiff
image_formats: Exif
image_formats: Icon
file_image_format: Png
image_codecs: 8
image_codecs: Built-in BMP Codec, mime: image/bmp, extension: *.BMP;*.DIB;*.RLE
image_codecs: Built-in JPEG Codec, mime: image/jpeg, extension: *.JPG;*.JPEG;*.JPE;*.JFIF
image_codecs: Built-in GIF Codec, mime: image/gif, extension: *.GIF
image_codecs: Built-in EMF Codec, mime: image/x-emf, extension: *.EMF
image_codecs: Built-in WMF Codec, mime: image/x-wmf, extension: *.WMF
image_codecs: Built-in TIFF Codec, mime: image/tiff, extension: *.TIF;*.TIFF
image_codecs: Built-in PNG Codec, mime: image/png, extension: *.PNG
image_codecs: Built-in ICO Codec, mime: image/x-icon, extension: *.ICO
Built-in PNG Codec, mime: image/png, extension: *.PNG

Solution 5 - C#

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).

Solution 6 - C#

Not to bother to on old topic, but to complete this discussion, I want to share my way to query all image formats, known by windows.

using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;

public static class ImageExtentions
{
    public static ImageCodecInfo GetCodecInfo(this System.Drawing.Image img)
    {
        ImageCodecInfo[] decoders = ImageCodecInfo.GetImageDecoders();
        foreach (ImageCodecInfo decoder in decoders)
            if (img.RawFormat.Guid == decoder.FormatID)
                return decoder;
        return null;
    }
}

Now you can use it as an an image extension as shown below:

public void Test(Image img)
{
    ImageCodecInfo info = img.GetCodecInfo();
    if (info == null)
        Trace.TraceError("Image format is unkown");
    else
        Trace.TraceInformation("Image format is " + info.FormatDescription);
}

Solution 7 - C#

Based on Alex's work above (which I actually vote as the solution, since it's one line - but I can't vote yet haha), I came up with the following function for an image library. It requires 4.0

  Public Enum Formats
    Unknown
    Bmp
    Emf
    Wmf
    Gif
    Jpeg
    Png
    Tiff
    Icon
  End Enum

  Public Shared Function ImageFormat(ByVal Image As System.Drawing.Image) As Formats
    If Not System.Enum.TryParse(Of Formats)(System.Drawing.Imaging.ImageCodecInfo.GetImageDecoders().ToList().[Single](Function(ImageCodecInfo) ImageCodecInfo.FormatID = Image.RawFormat.Guid).FormatDescription, True, ImageFormat) Then
      Return Formats.Unknown
    End If
  End Function

Solution 8 - C#

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; }

}

Solution 9 - C#

one weird problem i faced when i was trying to get the mime type using imagecodeinfo.. for some png files the guids were not exactly same...

first i was checking with the ImageCodecinfo and if code does not find the imageformat then i compared the imageformat using Matthias Wuttke's solution.

if both the above mentioned solution failed then used the extension method to get the file mime type..

if the mime type changes then the file also changes, we were calculating the downloaded files checksum to match with the checksum of the original file on the server .. so for us it was importent to get proper file as output.

Solution 10 - C#

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);

Solution 11 - C#

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);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionpencilslateView Question on Stackoverflow
Solution 1 - C#Christian C. SalvadóView Answer on Stackoverflow
Solution 2 - C#sebacipoView Answer on Stackoverflow
Solution 3 - C#AlexView Answer on Stackoverflow
Solution 4 - C#AlexView Answer on Stackoverflow
Solution 5 - C#JaredParView Answer on Stackoverflow
Solution 6 - C#Agent CKView Answer on Stackoverflow
Solution 7 - C#toddmoView Answer on Stackoverflow
Solution 8 - C#Nicholas PetersenView Answer on Stackoverflow
Solution 9 - C#Samuel JoyView Answer on Stackoverflow
Solution 10 - C#JohnnyIVView Answer on Stackoverflow
Solution 11 - C#JohnnyIVView Answer on Stackoverflow