Подтвердить что ты не робот

Найти формат изображения с помощью объекта Bitmap в С#

Я загружаю двоичные байты жесткого диска файла изображения и загружаю его в объект Bitmap. Как найти тип изображения [JPEG, PNG, BMP и т.д.] Из объекта Bitmap?

Выглядит тривиально. Но, не мог понять это!

Существует ли альтернативный подход?

Оцените свой ответ.

ОБНОВЛЕНО ПРАВИЛЬНОЕ РЕШЕНИЕ:

@CMS: Спасибо за правильный ответ!

Пример кода для этого.

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 a JPEG;
        else if (bitmap.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Png))
            //It a PNG;
    }
}
4b9b3361

Ответ 1

Если вы хотите узнать формат изображения, вы можете загрузить файл с помощью класса Image и проверить его RawFormat свойство:

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

Ответ 2

Вот мой метод расширения. Надеюсь, что это поможет кому-то.

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

Ответ 3

вот мой код для этого. Сначала необходимо загрузить полное изображение или заголовок (первые 4 байта) в массив байтов.

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

Ответ 4

конечно, вы можете. ImageFormat не означает многого. ImageCodecInfo имеет гораздо большее значение.

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>

код:

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

вывод отладки:

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

Ответ 5

Проще говоря, вы не можете. Причина в том, что Bitmap является типом изображения таким же образом, как JPEG, PNG и т.д. Как только вы загрузите изображение в растровое изображение изображения формата растрового изображения. Невозможно взглянуть на растровое изображение и понять исходную кодировку изображения (если она даже отличается от Bitmap).

Ответ 6

Основываясь на работе над Алексом выше (которую я на самом деле голосую как решение, так как это одна строка, но я не могу проголосовать еще хаха), я придумал следующую функцию для библиотеки изображений. Он требует 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

Ответ 7

Несколько простых методов расширения для типа Image для определения этого, основываясь на обнаружении Alex выше (ImageCodecInfo.GetImageDecoders()).

Это очень оптимизировано после первого вызова, поскольку статический ImageCodecsDictionary сохраняется в памяти (но только после того, как он был использован один раз).

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

}

Ответ 8

одна странная проблема, с которой я столкнулся, когда пытался получить тип mime с помощью imagecodeinfo.. для некоторых png файлов подсказки не были точно такими же...

Сначала я проверял с помощью ImageCodecinfo, и если код не нашел образ, тогда я сравнил изображение с помощью решения Matthias Wuttke.

Если оба вышеупомянутых решения не сработали, то используется метод расширения для получения типа файла mime.

если тип mime изменяется, тогда файл также изменяется, мы вычисляем контрольную сумму загруженных файлов, чтобы соответствовать контрольной сумме исходного файла на сервере.. так что для нас было важно получить правильный файл в качестве вывода.

Ответ 9

Не утруждайте себя старой темой, но для завершения этого обсуждения я хочу поделиться своим путем запросом всех форматов изображений, известных окнам.

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

Теперь вы можете использовать его как расширение изображения, как показано ниже:

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