Câu hỏi Tìm định dạng hình ảnh bằng cách sử dụng đối tượng Bitmap trong C #


Tôi đang tải các byte nhị phân của ổ cứng của tệp hình ảnh và tải nó vào một đối tượng Bitmap. Làm cách nào để tìm loại hình ảnh [JPEG, PNG, BMP etc] từ đối tượng Bitmap?

Có vẻ tầm thường. Nhưng, không thể hiểu được!

Có cách tiếp cận khác không?

Đánh giá cao phản hồi của bạn.

GIẢI PHÁP ĐÚNG CẬP NHẬT: 

@ CMS: Cảm ơn bạn đã trả lời đúng!

Mã mẫu để đạt được điều này.

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

76
2017-09-09 04:24


gốc


Bạn có thể thêm System.Drawing.Imaging không gian tên để sử dụng chỉ thị của bạn, để làm cho định dạng kiểm tra ít tiết hơn ... - CMS
@ CMS: Đồng ý! Muốn hiển thị không gian tên đầy đủ để biết thêm thông tin. - pencilslate
Hmmm ... Tôi đã thử kỹ thuật tương tự, nhưng nó không hoạt động. Tôi có một tệp PNG được nạp và khi tôi so sánh giá trị RawFormat của nó với tất cả các phiên bản ImageFormat. *, Không có trường hợp nào phù hợp. Giá trị RawFormat thực tế là {b96b3caf-0728-11d3-9d7b-0000f81ef32e}. - Igor Brejc


Các câu trả lời:


Nếu bạn muốn biết định dạng của hình ảnh, bạn có thể tải tệp bằng Hình ảnh và kiểm tra RawFormat bất động sản:

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

97
2017-09-09 04:36



Lưu ý: Có vẻ như img.RawFormat == ImageFormat.Jpeg không hoạt động. Bạn có sử dụng img.RawFormat.Equals(ImageFormat.Jpeg). - BlueRaja - Danny Pflughoeft
@BlueRaja, Yeah, tại sao vậy? Hầu hết các lớp .NET đều ghi đè cả phương thức Equals () và toán tử? Hoặc, có lẽ tôi đang phrasing nó sai - không. NET sử dụng phương thức .Equals () theo mặc định khi sử dụng toán tử ==? Tôi có sai không? - Pandincus
Gah! Không ngạc nhiên không hoạt động. Tôi giả định == đã làm các trick. Chỉ trích! Cảm ơn các bạn, đã cứu tôi nhiều lần rồi. - Ubiquitous Che
@Pandincus: không có đầu mối, xin lỗi. - BlueRaja - Danny Pflughoeft
Trừ khi nó bị ghi đè hoặc một trong số ít loại được tích hợp sẵn, == sử dụng bình đẳng tham chiếu, không Equals. Bên cạnh việc sử dụng Equals chính bạn, bạn có thể sử dụng tĩnh object.Equals(obj1, obj2) (cuộc gọi nào Equals) cho an toàn null đơn giản. - Tim S.


Đây là phương pháp mở rộng của tôi. Hy vọng điều này sẽ giúp một ai đó.

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

44
2018-01-31 14:45



Tôi không thể tin rằng .NET framework không có cái này và đó là cách duy nhất. Tôi thực sự bị sốc. - simonlchilds


đây là mã của tôi cho việc này. Bạn phải tải hình ảnh hoàn chỉnh hoặc tiêu đề (4 byte đầu tiên) vào một mảng byte trước tiên.

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

11
2018-02-25 17:04



Cần kiểm tra JPEG cho {255, 216, 255}. Đây là thông tin en.wikipedia.org/wiki/JPEG - Mirodil


tất nhiên bạn có thể. ImageFormat không có nghĩa là nhiều. ImageCodecInfo có ý nghĩa hơn nhiều.

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>

mã:

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

đầu ra gỡ lỗi:

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
2017-10-26 16:50



Tốt tìm Alex! Mặc dù điều này có vẻ lộn xộn, nhưng hãy xem các khái niệm cơ bản được chuyển thành một vài phương pháp tiện ích mở rộng rõ ràng bên dưới. - Nicholas Petersen


Nói đơn giản là bạn không thể. Lý do tại sao Bitmap là một loại hình ảnh giống như cách JPEG, PNG, v.v. Một khi bạn tải một hình ảnh vào một Bitmap hình ảnh của định dạng bitmap. Không có cách nào để nhìn vào một bitmap và hiểu được mã hóa ban đầu của hình ảnh (nếu nó thậm chí còn khác với Bitmap).


2
2017-09-09 04:26



Tôi nghĩ là trường hợp này Bitmap (gây nhầm lẫn) là tên của một lớp trong C #. Lớp Bitmap giữ một hình ảnh, có lẽ có thể là jpg, giff, bmp vv. Trong bất kỳ trường hợp nào khác, bạn hoàn toàn chính xác. - DarcyThomas


Dựa trên công việc của Alex ở trên (mà tôi thực sự bỏ phiếu là giải pháp, vì nó là một dòng - nhưng tôi không thể bỏ phiếu nhưng haha), tôi đã đưa ra chức năng sau cho một thư viện hình ảnh. Nó đòi hỏi 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

1
2018-02-17 14:36





Không bận tâm đến chủ đề cũ, nhưng để hoàn thành cuộc thảo luận này, tôi muốn chia sẻ theo cách của mình để truy vấn tất cả các định dạng hình ảnh, được biết đến bởi các cửa sổ.

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

Bây giờ bạn có thể sử dụng nó như là một phần mở rộng hình ảnh như hình dưới đây:

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

1
2017-10-29 15:20





Một vài phương pháp mở rộng rõ ràng về loại Image để xác định điều này, dựa trên tìm kiếm của Alex ở trên (ImageCodecInfo.GetImageDecoders()).

Điều này được tối ưu hóa cao sau khi cuộc gọi đầu tiên, như là tĩnh ImageCodecsDictionary được lưu trong bộ nhớ (nhưng chỉ sau khi nó đã được sử dụng một lần).

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
2017-11-14 07:29





một vấn đề lạ tôi phải đối mặt khi tôi đã cố gắng để có được loại mime bằng cách sử dụng imagecodeinfo .. đối với một số tập tin png các guids đã không chính xác giống nhau ...

đầu tiên tôi đã kiểm tra với ImageCodecinfo và nếu mã không tìm thấy imageformat thì tôi đã so sánh imageformat bằng cách sử dụng giải pháp của Matthias Wuttke.

nếu cả hai giải pháp được đề cập ở trên không thành công thì sử dụng phương thức mở rộng để lấy loại tệp mime ..

nếu loại mime thay đổi thì tệp cũng thay đổi, chúng tôi đã tính toán các tệp đã tải xuống để kiểm tra khớp với tổng kiểm của tệp gốc trên máy chủ .. vì vậy đối với chúng tôi, tệp đó đã được nhập để nhận tệp thích hợp làm đầu ra.


0
2018-03-12 14:37





Chất CK, Tôi thích phương pháp mở rộng của bạn và thêm một chuỗi quá tải, cộng với tôi đã giảm mã cho phương pháp của bạn:

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
2018-03-29 03:27





Phương pháp đơn giản nhất được cung cấp bởi Cesare Imperiali như thế này:

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

Tuy nhiên, .ToString () cho một .jpg trả về "[ImageFormat: b96b3cae-0728-11d3-9d7b-0000f81ef32e]" thay vì "Jpeg". Nếu điều đó quan trọng với bạn, đây là giải pháp của tôi:

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
2018-03-27 03:02