Determinar el tipo de archivo de una imagen
-
09-06-2019 - |
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.
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:
- JPG: 0xFF 0xD8
- PNG: 0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A
- GIF: 'G' 'I' 'F'
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.