Pregunta

Estoy descargando algunas imágenes de un servicio que no siempre incluyen un tipo de contenido y no proporciona una extensión para el archivo que estoy descargando (ugh, no pregunten).

¿Cuál es la mejor manera de determinar el formato de la imagen en .NETA?

La aplicación que es la lectura de estas imágenes descargadas debe tener una extensión de archivo correcto o todo el infierno se rompe suelto.

¿Fue útil?

Solución

Probablemente, la más fácil, sería el uso de la Imagen.FromFile() y, a continuación, utilizar la RawFormat propiedad, tal como ya se sabe acerca de la magia de los bits en los encabezados de los formatos más comunes, como este:

Image i = Image.FromFile("c:\\foo");
if (System.Drawing.Imaging.ImageFormat.Jpeg.Equals(i.RawFormat)) 
    MessageBox.Show("JPEG");
else if (System.Drawing.Imaging.ImageFormat.Gif.Equals(i.RawFormat))
    MessageBox.Show("GIF");
//Same for the rest of the formats

Otros consejos

Todos los formatos de imagen de conjunto inicial de bytes a un valor en particular:

De la búsqueda para "formato de archivo jpg" sustitución de jpg con el otro formato de archivo que usted necesita identificar.

Como Garth recomienda, no es un base de datos de ejemplo "magic numbers" muestra el tipo de archivo de muchos archivos.Si usted tiene que detectar una gran cantidad de diferentes tipos de archivo que vale la pena mirar a través de él para encontrar la información que necesita.Si necesita ampliar para abarcar muchos, muchos tipos de archivo, mira a los asociados archivo de comandos que implementa el motor a utilizar la base de datos correctamente (no es trivial para muchos formatos de archivo, y es casi un proceso estadístico)

-Adam

Usted puede utilizar el código siguiente sin referencia de Sistema.El dibujo y la innecesaria creación de la Imagen del objeto.También puede utilizar Alex solución, incluso sin corriente y de referencia del Sistema.IO.

public enum ImageFormat
{
    bmp,
    jpeg,
    gif,
    tiff,
    png,
    unknown
}

public static ImageFormat GetImageFormat(Stream stream)
{
    // 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

    var buffer = new byte[4];
    stream.Read(buffer, 0, buffer.Length);

    if (bmp.SequenceEqual(buffer.Take(bmp.Length)))
        return ImageFormat.bmp;

    if (gif.SequenceEqual(buffer.Take(gif.Length)))
        return ImageFormat.gif;

    if (png.SequenceEqual(buffer.Take(png.Length)))
        return ImageFormat.png;

    if (tiff.SequenceEqual(buffer.Take(tiff.Length)))
        return ImageFormat.tiff;

    if (tiff2.SequenceEqual(buffer.Take(tiff2.Length)))
        return ImageFormat.tiff;

    if (jpeg.SequenceEqual(buffer.Take(jpeg.Length)))
        return ImageFormat.jpeg;

    if (jpeg2.SequenceEqual(buffer.Take(jpeg2.Length)))
        return ImageFormat.jpeg;

    return ImageFormat.unknown;
}

Adam apunta exactamente en la dirección correcta.

Si quieres saber cómo sentido casi cualquier archivo de, buscar en la base de datos detrás de la file comando en UNIX, Linux, o Mac OS X de la máquina.

file utiliza una base de datos de "números mágicos" — aquellos primeros bytes de Adam en la lista — a sentido un tipo de archivo. man file le dirá dónde encontrar la base de datos en su máquina, por ejemplo, /usr/share/file/magic. man magic le dirá a su formato.

Usted puede escribir su propio código de detección basado en lo que ves en la base de datos, el uso de pre-empaquetado de las bibliotecas (por ejemplo, python-magia), o — si eres realmente aventureros de implementar .NET versión de libmagic.No pude encontrar uno, y la esperanza de otro miembro puede apuntar uno.

En caso de no tener una máquina UNIX práctico, la base de datos se parece a esto:

# PNG [Portable Network Graphics, or "PNG's Not GIF"] images
# (Greg Roelofs, newt@uchicago.edu)
# (Albert Cahalan, acahalan@cs.uml.edu)
#
# 137 P N G \r \n ^Z \n [4-byte length] H E A D [HEAD data] [HEAD crc] ...
#
0       string          \x89PNG         PNG image data,
>4      belong          !0x0d0a1a0a     CORRUPTED,
>4      belong          0x0d0a1a0a
>>16    belong          x               %ld x
>>20    belong          x               %ld,
>>24    byte            x               %d-bit
>>25    byte            0               grayscale,
>>25    byte            2               \b/color RGB,
>>25    byte            3               colormap,
>>25    byte            4               gray+alpha,
>>25    byte            6               \b/color RGBA,
#>>26   byte            0               deflate/32K,
>>28    byte            0               non-interlaced
>>28    byte            1               interlaced
1       string          PNG             PNG image data, CORRUPTED

# GIF
0       string          GIF8            GIF image data
>4      string          7a              \b, version 8%s,
>4      string          9a              \b, version 8%s,
>6      leshort         >0              %hd x
>8      leshort         >0              %hd
#>10    byte            &0x80           color mapped,
#>10    byte&0x07       =0x00           2 colors
#>10    byte&0x07       =0x01           4 colors
#>10    byte&0x07       =0x02           8 colors
#>10    byte&0x07       =0x03           16 colors
#>10    byte&0x07       =0x04           32 colors
#>10    byte&0x07       =0x05           64 colors
#>10    byte&0x07       =0x06           128 colors
#>10    byte&0x07       =0x07           256 colors

Buena suerte!

No hay manera programática para determinar la imagen de su tipo mime.

No hay clase Sistema.De dibujo.La proyección de imagen.ImageCodecInfo.

Esta clase tiene propiedades MimeType y FormatID.También tiene un método GetImageEncoders que devolver la colección de todos los codificadores.Es fácil crear Diccionario de tipos mime indexados por id de formato.

Clase Sistema.De dibujo.Imagen tienen la propiedad RawFormat de Tipo Sistema.De dibujo.La proyección de imagen.ImageFormat que tiene la propiedad Guid que es equivalente a la propiedad FormatID de clase Sistema.De dibujo.La proyección de imagen.ImageCodecInfo, y que es clave para tomar MIMETYPE de diccionario.

Ejemplo:

Método estático para crear el diccionario de tipos mime

static Dictionary<Guid, string> GetImageFormatMimeTypeIndex()
{
  Dictionary<Guid, string> ret = new Dictionary<Guid, string>();

  var encoders = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();

  foreach(var e in encoders)
  {
    ret.Add(e.FormatID, e.MimeType);
  }

  return ret;
}

Uso:

Dictionary<Guid, string> mimeTypeIndex = GetImageFormatMimeTypeIndex();

FileStream imgStream = File.OpenRead(path);
var image = System.Drawing.Image.FromStream(imgStream);
string mimeType = mimeTypeIndex[image.RawFormat.Guid];

Trate de cargar el flujo en un Sistema.IO.BinaryReader.

A continuación usted necesitará para referirse a las especificaciones para cada formato de imagen que necesita, y la carga de la cabecera byte por byte para comparar con las especificaciones.Por ejemplo, aquí están los PNG especificaciones

Añadió:El real la estructura del archivo para PNG.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top