Noté un par de problemas con todas las funciones anteriores. Primero de todos - Imagen.FromFile abre la imagen dada y luego causará un error de archivo abierto. Quien quiera abrir un archivo de imagen dado por cualquier razón. Incluso la aplicación en sí misma, así que cambié usando Image.FromStream.
Después de cambiar los cambios de tipo de excepción de OutOfMemoryException a ArgumentException por algún motivo poco claro para mí. (Probablemente .net framework bug?)
También si .net agregará más formatos de archivo de imagen que actualmente lo comprobaremos por función - tiene sentido primero intentar cargar la imagen si solo falla luego de eso para informar error.
Así que mi código es ahora así:
try {
using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read))
{
Image im = Image.FromStream(stream);
// Do something with image if needed.
}
}
catch (ArgumentException)
{
if(!IsValidImageFormat(path))
return SetLastError("File '" + fileName + "' is not a valid image");
throw;
}
Dónde:
/// <summary>
/// Check if we have valid Image file format.
/// </summary>
/// <param name="path"></param>
/// <returns>true if it's image file</returns>
public static bool IsValidImageFormat(String path)
{
using (FileStream fs = File.OpenRead(path))
{
byte[] header = new byte[10];
fs.Read(header, 0, 10);
foreach (var pattern in new byte[][] {
Encoding.ASCII.GetBytes("BM"),
Encoding.ASCII.GetBytes("GIF"),
new byte[] { 137, 80, 78, 71 }, // PNG
new byte[] { 73, 73, 42 }, // TIFF
new byte[] { 77, 77, 42 }, // TIFF
new byte[] { 255, 216, 255, 224 }, // jpeg
new byte[] { 255, 216, 255, 225 } // jpeg canon
})
{
if (pattern.SequenceEqual(header.Take(pattern.Length)))
return true;
}
}
return false;
} //IsValidImageFormat
Por qué no envuelva a ese código en un bloque try ... catch, y si se lanza esta excepción, puede lo considera "inválido"? Por supuesto, esta es una heurística ingenua, pero cumple su función. Cualquier otra cosa igual tendrá que abrir el archivo, por lo que no va a guardar una cantidad significativa en cuanto a rendimiento, independientemente de IMO. –
Vea también: http://stackoverflow.com/questions/9354747/how-can-i-determine-if-a-file-is-an-image-file-in-net – Daryl