I noticed a couple of problems with all of the above functions. First of all, Image.FromFile opens the given image, and then causes an open file error, whoever wants to open this image file for any reason. Even the application itself - so I switched using Image.FromStream.
After you change the api, the type of exception will change from OutOfMemoryException to ArgumentException for some reasons I don't understand. (Perhaps a .net network error?)
In addition, if .net adds more image file formats than it currently does, we will check by function - it makes sense to try downloading the image first, if only then failed, only then report an error.
So my code looks like this:
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; }
Where:
/// <summary> /// Check if we have valid Image file format. /// </summary> /// <param name="path"></param> /// <returns>true if it 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