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?
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;
}
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; }
}
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;
}
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);
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);
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).