Заметил пару проблем со всеми функциями выше.
Прежде всего - Image.FromFile открывает данное изображение и впоследствии вызывает ошибку открытия файла, если кто-либо захочет открыть данный файл изображения по любой причине. Даже само приложение - поэтому я переключился с использованием Image.FromStream.
После переключения api - тип исключения меняется с OutOfMemoryException на ArgumentException по какой-то непонятной для меня причине. (Вероятно, ошибка .net Framework?)
Также, если .net добавит больше поддерживаемых форматов файлов изображений, чем мы будем проверять по функциям - имеет смысл сначала попытаться загрузить изображение, если только в этом случае произойдет сбой - только после этого сообщить об ошибке.
Итак, мой код теперь выглядит так:
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;
}
Где:
/// <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