ASP.NET: How to check if an image is a GIF, specifically images with changed extensions
I've taken over work for the custom forums that a previous developer created at my job, and came across a minor b开发者_如何学Pythonug. We don't allow animated GIFs as avatars in the forums. However, if someone were to take an animated GIF, rename it to imagename.jpeg, and then upload it, the forums will show the image as being animated.
It's a very odd bug as I didn't even think it played the animation if the extension wasn't .gif.
So my question is: Is there a way to check (in .NET 2.0) if an image is an animated gif, even if the extension isn't?
Bara
You could open the file and analyze its header to see if it is a GIF. According to http://www.onicos.com/staff/iz/formats/gif.html, the first 3 bytes of the header should be "GIF".
The best way to detect if an image file is an animated GIF on ASP.NET is via the .NET API itself. Here is a sample code in VB.NET:
Imports System.Drawing
Imports System.Drawing.Imaging
Public Class ImageHelper
Shared Function IsAnimatedGif(filepath As String) As Boolean
Return GetFrameCount(filepath) > 1
End Function
Shared Function GetFrameCount(filepath As String) As Integer
Using bitmap As New Bitmap(filepath)
Dim dimensions As New FrameDimension(bitmap.FrameDimensionsList(0))
Return bitmap.GetFrameCount(dimensions)
End Using
End Function
End Class
Same sample using C#:
using System.Drawing;
using System.Drawing.Imaging;
public class ImageHelper
{
public static bool IsAnimatedGif(string filepath)
{
return GetFrameCount(filepath) > 1;
}
public static int GetFrameCount(string filepath)
{
using (Bitmap bitmap = new Bitmap(filepath))
{
FrameDimension dimensions = new FrameDimension(bitmap.FrameDimensionsList[0]);
return bitmap.GetFrameCount(dimensions);
}
}
}
I am not sure if this works, but check last post:
http://forums.asp.net/p/1188302/2033730.aspx
For convenience, here is the PHP code converted to working C# code:
byte[] byteCode1 = { 0x00, 0x21, 0xF9, 0x04 };
byte[] byteCode2 = { 0x00, 0x2C };
String strTemp;
byte[] byteContents;
bool bIsAnimatedGif = false;
int iCount;
int iPos = 0;
int iPos1;
int iPos2;
Stream st = null;
// st is a stream previously opened on a file
byteContents = new byte[st.Length];
st.Read(byteContents, 0, (int)st.Length);
strTemp = System.Text.Encoding.ASCII.GetString(byteContents);
byteContents = null;
iCount = 0;
while (iCount < 2)
{
iPos1 = strTemp.IndexOf(System.Text.Encoding.ASCII.GetString(byteCode1), iPos);
if (iPos1 == -1) break;
iPos = iPos1 + 1;
iPos2 = strTemp.IndexOf(System.Text.Encoding.ASCII.GetString(byteCode2), iPos);
if (iPos2 == -1) break;
if ((iPos1 + 8) == iPos2)
iCount++;
iPos = iPos2 + 1;
}
if (iCount > 1) bIsAnimatedGif = true;
Here's a snippet of PHP (snagged from the PHP forums) that does exactly what you're looking for. Converting it to .NET should be pretty simple.
function is_animated_gif($filename)
{
$filecontents=file_get_contents($filename);
$str_loc=0;
$count=0;
while ($count < 2)
{
$where1=strpos($filecontents,"\x00\x21\xF9\x04",$str_loc);
if ($where1 === FALSE)
{
break;
}
else
{
$str_loc=$where1+1;
$where2=strpos($filecontents,"\x00\x2C",$str_loc);
if ($where2 === FALSE)
{
break;
}
else
{
if ($where1+8 == $where2)
{
$count++;
}
$str_loc=$where2+1;
}
}
}
if ($count > 1)
{
return(true);
}
else
{
return(false);
}
}
精彩评论