Pytanie Znajdź format obrazu za pomocą obiektu Bitmap w języku C #


Ładuję binarne bajty dysku twardego pliku obrazu i ładuję go do obiektu Bitmap. Jak znaleźć typ obrazu [JPEG, PNG, BMP itd.] Z obiektu Bitmap?

Wygląda banalnie. Ale nie mogłem tego rozgryźć!

Czy istnieje alternatywne podejście?

Doceń swoją odpowiedź.

ZAKTUALIZOWANE PRAWIDŁOWE ROZWIĄZANIE: 

@CMS: Dzięki za poprawną odpowiedź!

Przykładowy kod do osiągnięcia tego.

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


pochodzenie


Możesz dodać System.Drawing.Imaging przestrzeni nazw do używanych dyrektyw, aby sprawdzenie formatu było mniej szczegółowe ... - CMS
@CMS: Zgoda! Chciał wyświetlić pełną przestrzeń nazw, aby uzyskać dodatkowe informacje. - pencilslate
Hmmm ... Próbowałem tej samej techniki, ale to nie działa. Mam załadowany PNG i kiedy porównam jego wartość RawFormat do wszystkich instancji ImageFormat. *, Żadna z nich nie pasuje. Rzeczywista wartość formatu RawFormat to {b96b3caf-0728-11d3-9d7b-0000f81ef32e}. - Igor Brejc


Odpowiedzi:


Jeśli chcesz poznać format obrazu, możesz załadować plik za pomocą Obraz klasa i sprawdź jego RawFormat własność:

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



Uwaga: Wygląda na to, że img.RawFormat == ImageFormat.Jpeg nie działa. ty mieć używać img.RawFormat.Equals(ImageFormat.Jpeg). - BlueRaja - Danny Pflughoeft
@ BlueRaja, tak, dlaczego to jest? Czy większość klas .NET nie zastępuje metody Equals () i operatora? Lub, być może I'm phrasing to źle - nie. NET używać metody .Equals () domyślnie podczas korzystania z operatora ==? Czy jestem niepoprawny? - Pandincus
Gah! Nie cud to nie działa. Założę się, że == zrobił lewę. Cholerny! Dzięki chłopaki, uratowaliście mi teraz trochę czasu. - Ubiquitous Che
@Pandincus: nie ma pojęcia, przepraszam. - BlueRaja - Danny Pflughoeft
O ile nie zostanie on zastąpiony lub jeden z kilku wbudowanych typów, == używa równości odniesienia, nie Equals. Poza używaniem Equals siebie, możesz użyć statycznego object.Equals(obj1, obj2) (która dzwoni Equals) dla prostego bezpieczeństwa zerowego. - Tim S.


Oto moja metoda rozszerzenia. Mam nadzieję, że to pomoże komuś.

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



Nie mogę uwierzyć, że środowisko .NET nie ma tego zapakowanego i że jest to jedyny sposób. Jestem w szoku. - simonlchilds


oto mój kod do tego. Musisz najpierw załadować pełny obraz lub nagłówek (pierwsze 4 bajty) do tablicy bajtów.

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



JPEG należy sprawdzić pod kątem {255, 216, 255}. Oto informacje en.wikipedia.org/wiki/JPEG - Mirodil


oczywiście, że możesz. ImageFormat nie znaczy wiele. ImageCodecInfo ma dużo więcej znaczenia.

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>

kod:

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

wyjście debugowania:

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



Dobra znajo Alex! Choć wygląda to niechlujnie, ale zobacz podstawy obrócone w kilka czystych metod rozszerzenia poniżej. - Nicholas Petersen


Po prostu nie możesz. Powodem, dla którego ta mapa bitowa jest rodzajem obrazu w taki sam sposób, jak JPEG, PNG, itp. Po załadowaniu obrazu do bitmapy obraz mapy bitowej. Nie ma sposobu, aby spojrzeć na bitmapę i zrozumieć oryginalne kodowanie obrazu (jeśli jest nawet inny niż Bitmapa).


2
2017-09-09 04:26



Myślę, że w tym przypadku bitmap (myląco) to nazwa klasy w języku C #. Klasa Bitmap zawiera obraz, który prawdopodobnie może być jpg, giff, bmp itd. W innych okolicznościach tak, masz całkowitą rację. - DarcyThomas


Bazując na powyższej pracy Alexa (którą faktycznie głosuję jako rozwiązanie, ponieważ jest to jedna linia - ale nie mogę głosować jeszcze haha), wymyśliłem następującą funkcję dla biblioteki obrazów. Wymaga 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





Nie przejmuj się starym tematem, ale aby dokończyć tę dyskusję, chcę podzielić się moją drogą z zapytaniami wszystko formaty obrazów znane z systemu 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;
    }
}

Teraz możesz użyć go jako rozszerzenia obrazu, jak pokazano poniżej:

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