C #에서 Bitmap 개체를 사용하여 이미지 형식 찾기


83

이미지 파일 하드 드라이브의 바이너리 바이트를로드하고 Bitmap 개체에로드합니다. Bitmap 객체에서 이미지 유형 [JPEG, PNG, BMP 등]을 찾으려면 어떻게합니까?

사소 해 보입니다. 그러나 그것을 알아낼 수 없었습니다!

다른 방법이 있습니까?

귀하의 답변에 감사드립니다.

업데이트 된 올바른 솔루션 :

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

3
당신은 추가 할 수 있습니다 System.Drawing.Imaging, 귀하의 사용 지침에 네임 스페이스를 덜 장황 형식 검사를하기 위해 ...
기독교 C. Salvadó

@CMS : 동의합니다! 추가 정보를 위해 전체 네임 스페이스를 표시하고 싶었습니다.
pencilslate

2
흠 ... 같은 기술을 시도했지만 작동하지 않습니다. PNG가로드되어 있고 RawFormat 값을 모든 ImageFormat. * 인스턴스와 비교할 때 일치하는 항목이 없습니다. 실제 RawFormat 값은 {b96b3caf-0728-11d3-9d7b-0000f81ef32e}입니다.
Igor Brejc 2010

답변:


106

이미지의 형식을 알고 싶다면 Image 클래스를 사용 하여 파일을로드 하고 RawFormat 속성을 확인할 수 있습니다.

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

29
참고 : img.RawFormat == ImageFormat.Jpeg작동하지 않는 것 같습니다. 당신 사용하는 img.RawFormat.Equals(ImageFormat.Jpeg).
BlueRaja-Danny Pflughoeft 2010

1
@ BlueRaja, 그래, 왜 그럴까요? 대부분의 .NET 클래스가 Equals () 메서드와 연산자를 모두 재정의하지 않습니까? 또는 내가 잘못 표현한 것일 수도 있습니다. == 연산자를 사용할 때 .NET이 기본적으로 .Equals () 메서드를 사용하지 않습니까? 내가 틀렸나 요?
Pandincus 2010

아! 없음 당연 작동되지 않았습니다. 나는 ==이 트릭을했다고 가정했습니다. 제길! 고마워요, 지금 막 많은 시간을 절약했습니다.
Ubiquitous Che

1
재정의되거나 몇 가지 내장 유형 중 하나가 ==아닌 경우 Equals. Equals자신을 사용하는 것 외에도 간단한 null 안전을 위해 정적 object.Equals(obj1, obj2)(을 호출 Equals)을 사용할 수 있습니다 .
Tim S.

58

내 확장 방법은 다음과 같습니다. 이것이 누군가를 돕기를 바랍니다.

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

9
.NET 프레임 워크에 이것이 포함되어 있지 않고 이것이 유일한 방법이라고 믿을 수 없습니다. 나는 실제로 충격을 받고 있습니다.
simonlchilds

18

여기에 대한 내 코드가 있습니다. 먼저 전체 이미지 또는 헤더 (처음 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;
}

1
{255, 216, 255}에 대해 JPEG를 확인해야합니다. 여기에 정보입니다 en.wikipedia.org/wiki/JPEG은
Mirodil

9

물론 당신은 할 수. 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

알렉스를 찾아 줘! 이것은 지저분 해 보이지만 기본은 아래의 두 가지 깨끗한 확장 방법으로 바뀌 었습니다.
Nicholas Petersen 2013

2

단순히 말할 수 없습니다. 그 이유는 Bitmap이 JPEG, PNG 등과 같은 방식의 이미지 유형이기 때문입니다. 이미지를 비트 맵으로로드하면 비트 맵 형식의 이미지가됩니다. 비트 맵을보고 이미지의 원래 인코딩을 이해할 수있는 방법이 없습니다 (비트 맵과 다른 경우).


1
나는이 경우 Bitmap (혼란스럽게도)이 C #의 클래스 이름이라고 생각합니다. Bitmap 클래스는 아마도 jpg, giff, bmp 등을 할 수있는 이미지를 가지고 있습니다. 다른 어떤 상황에서도 당신은 절대적으로 맞습니다.
DarcyThomas 2016-04-25

2

이전 주제에 대해 신경 쓰지 않고이 토론을 완료하기 위해 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;
    }
}

이제 아래와 같이 이미지 확장자로 사용할 수 있습니다.

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

위의 Alex의 작업을 기반으로 (실제로 한 줄이기 때문에 솔루션으로 투표했지만 아직 하하 투표 할 수 없음) 이미지 라이브러리에 대한 다음 기능을 생각해 냈습니다. 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

0

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

}

0

내가 imagecodeinfo를 사용하여 MIME 유형을 얻으려고 할 때 직면 한 이상한 문제 하나 .. 일부 png 파일의 경우 guid가 정확히 동일하지 않았습니다 ...

먼저 ImageCodecinfo로 확인하고 코드가 이미지 형식을 찾지 못하면 Matthias Wuttke의 솔루션을 사용하여 이미지 형식을 비교했습니다.

위에서 언급 한 솔루션이 모두 실패한 경우 확장 방법을 사용하여 파일 MIME 유형을 가져옵니다.

MIME 유형이 변경되면 파일도 변경됩니다. 서버에있는 원본 파일의 체크섬과 일치하도록 다운로드 한 파일 체크섬을 계산했습니다. .. 따라서 적절한 파일을 출력으로 가져 오는 것이 중요했습니다.


0

Agent CK , 나는 당신의 확장 방법이 마음에 들었고 문자열 오버로드를 추가했고 당신의 방법에 대한 코드를 줄였습니다.

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

가장 간단한 방법은 Cesare Imperiali 에서 다음과 같이 제공했습니다 .

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

그러나 .jpg의 .ToString ()은 "Jpeg"대신 "[ImageFormat : b96b3cae-0728-11d3-9d7b-0000f81ef32e]"를 반환합니다. 그게 중요하다면 여기 내 해결책이 있습니다.

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);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.