C# 确定文件是否为图像
我在一个目录中循环并复制所有文件。现在我正在用C# 确定文件是否为图像,c#,image,file,C#,Image,File,我在一个目录中循环并复制所有文件。现在我正在用string.EndsWith检查“.jpg”或“.png”等 有没有更优雅的方法来确定一个文件是否是一个图像(任何图像类型),而不必像上面那样进行黑客检查?检查该文件是否有错误。(中也提到了链接中的信息) PNG文件的前八个字节始终包含以下(十进制)值:137 80 78 71 13 10 26 10 这是一个简单的例子 public static readonly List<string> ImageExtensions = new
string.EndsWith
检查“.jpg”
或“.png”
等
有没有更优雅的方法来确定一个文件是否是一个图像(任何图像类型),而不必像上面那样进行黑客检查?检查该文件是否有错误。(中也提到了链接中的信息)
PNG文件的前八个字节始终包含以下(十进制)值:137 80 78 71 13 10 26 10
这是一个简单的例子
public static readonly List<string> ImageExtensions = new List<string> { ".JPG", ".JPE", ".BMP", ".GIF", ".PNG" };
private void button_Click(object sender, RoutedEventArgs e)
{
var folder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
var files = Directory.GetFiles(folder);
foreach(var f in files)
{
if (ImageExtensions.Contains(Path.GetExtension(f).ToUpperInvariant()))
{
// process image
}
}
}
public static readonly List ImageExtensions=新列表{.JPG“,.JPE“,.BMP“,.GIF“,.PNG”};
私有无效按钮\u单击(对象发送者,路由目标e)
{
var folder=Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
var files=Directory.GetFiles(文件夹);
foreach(文件中的var f)
{
if(ImageExtensions.Contains(Path.GetExtension(f.ToUpperInvariant()))
{
//处理图像
}
}
}
查看是否有帮助
编辑:另外,Image.FromFile(..).RawFormat可能会有所帮助。如果文件不是图像,它可能会引发异常。这不是您需要的答案。但如果是互联网,那么就输入 我不确定此解决方案的性能缺陷是什么,但您不能在try块中对文件执行一些图像功能,如果它不是图像,则会失败并落入catch块吗
using System.Collections.Generic;
using System.IO;
using System.Linq;
public static class Extension
{
public static bool IsImage(this Stream stream)
{
stream.Seek(0, SeekOrigin.Begin);
List<string> jpg = new List<string> { "FF", "D8" };
List<string> bmp = new List<string> { "42", "4D" };
List<string> gif = new List<string> { "47", "49", "46" };
List<string> png = new List<string> { "89", "50", "4E", "47", "0D", "0A", "1A", "0A" };
List<List<string>> imgTypes = new List<List<string>> { jpg, bmp, gif, png };
List<string> bytesIterated = new List<string>();
for (int i = 0; i < 8; i++)
{
string bit = stream.ReadByte().ToString("X2");
bytesIterated.Add(bit);
bool isImage = imgTypes.Any(img => !img.Except(bytesIterated).Any());
if (isImage)
{
return true;
}
}
return false;
}
}
此策略可能不是所有情况下的最佳解决方案,但在我目前使用它的情况下,它有一个主要优势:
您可以使用计划用于为测试函数处理图像(如果是图像)的任何函数。通过这种方式,您可以测试所有当前图像类型,但也可以扩展到未来的图像类型,而无需将新的图像扩展添加到支持的图像类型列表中
有人看到这个策略有什么缺点吗?我使用以下方法。它使用内置图像解码器检索系统识别为图像文件的扩展名列表,然后将这些扩展名与传入的文件名扩展名进行比较。返回一个简单的TRUE/FALSE
public static bool IsRecognisedImageFile(string fileName)
{
string targetExtension = System.IO.Path.GetExtension(fileName);
if (String.IsNullOrEmpty(targetExtension))
return false;
else
targetExtension = "*" + targetExtension.ToLowerInvariant();
List<string> recognisedImageExtensions = new List<string>();
foreach (System.Drawing.Imaging.ImageCodecInfo imageCodec in System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders())
recognisedImageExtensions.AddRange(imageCodec.FilenameExtension.ToLowerInvariant().Split(";".ToCharArray()));
foreach (string extension in recognisedImageExtensions)
{
if (extension.Equals(targetExtension))
{
return true;
}
}
return false;
}
公共静态bool IsRecognisedImageFile(字符串文件名)
{
字符串targetExtension=System.IO.Path.GetExtension(文件名);
if(String.IsNullOrEmpty(targetExtension))
返回false;
其他的
targetExtension=“*”+targetExtension.ToLowerInvariant();
List recognizedImageExtensions=新列表();
foreach(System.Drawing.Imaging.ImageCodeInfo imageCodec在System.Drawing.Imaging.ImageCodeInfo.GetImageEncoders()中)
识别ImageExtensions.AddRange(imageCodec.FilenameExtension.ToLowerInvariant().Split(“;”.ToCharArray());
foreach(识别的ImageExtensions中的字符串扩展名)
{
if(扩展名等于(targetExtension))
{
返回true;
}
}
返回false;
}
这将查看文件的前几个字节并确定它是否为图像
using System.Collections.Generic;
using System.IO;
using System.Linq;
public static class Extension
{
public static bool IsImage(this Stream stream)
{
stream.Seek(0, SeekOrigin.Begin);
List<string> jpg = new List<string> { "FF", "D8" };
List<string> bmp = new List<string> { "42", "4D" };
List<string> gif = new List<string> { "47", "49", "46" };
List<string> png = new List<string> { "89", "50", "4E", "47", "0D", "0A", "1A", "0A" };
List<List<string>> imgTypes = new List<List<string>> { jpg, bmp, gif, png };
List<string> bytesIterated = new List<string>();
for (int i = 0; i < 8; i++)
{
string bit = stream.ReadByte().ToString("X2");
bytesIterated.Add(bit);
bool isImage = imgTypes.Any(img => !img.Except(bytesIterated).Any());
if (isImage)
{
return true;
}
}
return false;
}
}
我们可以使用名称空间系统中的图像和图形类;做我们的工作。如果代码正常工作,则它是一个图像,否则它不是。那就是让DotNet框架为我们做这项工作。 该守则—
public string CheckFile(file)
{
string result="";
try
{
System.Drawing.Image imgInput = System.Drawing.Image.FromFile(file);
System.Drawing.Graphics gInput = System.Drawing.Graphics.fromimage(imgInput);
Imaging.ImageFormat thisFormat = imgInput.RawFormat;
result="It is image";
}
catch(Exception ex)
{
result="It is not image";
}
return result;
}
MimeMapping.GetMimeMapping
生成以下结果:
- file.jpg:image/jpeg
- file.gif:image/gif
- file.jpeg:image/jpeg
- file.png:image/png
- file.bmp:image/bmp
- file.tiff:image/tiff
- file.svg:应用程序/八位字节流
在大多数情况下,file.svg不返回image/MIME类型是可行的,因为您可能不会像处理标量图像那样处理向量图像。在检查MIME类型时,请注意SVG确实具有标准的MIME类型image/SVG+xml,即使
GetMimeMapping
没有返回它。如果您想在完全读取图像文件之前快速验证图像文件,除了比较文件扩展名外,还可以检查其头以查找文件签名(以下代码isvalidImage文件()
检查是否有BMP、GIF87a、GIF89a、PNG、TIFF、JPEG)
我的简单代码
public static List<string> GetAllPhotosExtensions()
{
var list = new List<string>();
list.Add(".jpg");
list.Add(".png");
list.Add(".bmp");
list.Add(".gif");
list.Add(".jpeg");
list.Add(".tiff");
return list;
}
这就是我所使用的——它只是@dylmcc答案的一个调整,使其更具可读性
public static bool IsRecognisedImageFile(string fileName)
{
string targetExtension = System.IO.Path.GetExtension(fileName);
if (String.IsNullOrEmpty(targetExtension))
{
return false;
}
var recognisedImageExtensions = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders().SelectMany(codec => codec.FilenameExtension.ToLowerInvariant().Split(';'));
targetExtension = "*" + targetExtension.ToLowerInvariant();
return recognisedImageExtensions.Contains(targetExtension);
}
这是一个棘手的问题。如果文件不是映像,将引发异常。从中我们可以检查文件是否为映像
using (Stream stream = File.OpenRead(file))
{
try
{
using (Image sourceImage = Image.FromStream(stream, false, false))
{
}
}
catch (Exception x)
{
if (x.Message.Contains("not valid"))
{
Console.Write("This is not a Image.");
}
}
}
他说他正在检查string.EndsWith是否来自我收集的内容是的,但这仍然是一个字符串比较。如果我将.jpf文件重命名为.txt呢?这个问题有两种可能的解释:要么“EndsWith”是hacky(在这种情况下,这个答案就是OP想要的),或者说“使用文件名”是不礼貌的,在这种情况下@MitchWheat的答案是OP想要的。我更喜欢Mitch的,但两者都投了赞成票。如果使用扩展名,请确保在进行比较之前将其转换为小写。(例如,许多数码相机都会生成.JPG文件。)哇,Clarion仍然存在!这是一个惊喜-我在95年左右在Clarion上切了一两颗牙齿。请注意,第二到第六个字符是“PNG\r\n”。很抱歉,您的链接不再有效。我有一个403错误。是的,链接已失效:(最初于2008年7月发布的链接内容已存档在上。是否有扩展不够好的原因?另请参阅:@peterchen是的,可能文件是图像,但不知何故重命名为其他名称,因为您缺少许多可能的图像类型。一些键入:应返回IsImage(流,输出图像类型);而不是返回stream.IsImage(out imageType);应该是int-largestByteHeader=ImageTypes.Max(img=>img.Key.Length),而不是int-largestByteHeader=ImageTypes.Max(img=>img.Value.Length)实现您刚才编写的内容,并查看它是否编译您的编辑在
int-largestByteHeader=ImageTypes.Max上有一个小错误(img=>img.Value.Length);
line-长度sho
public static List<string> GetAllPhotosExtensions()
{
var list = new List<string>();
list.Add(".jpg");
list.Add(".png");
list.Add(".bmp");
list.Add(".gif");
list.Add(".jpeg");
list.Add(".tiff");
return list;
}
public static bool IsPhoto(string fileName)
{
var list = FileListExtensions.GetAllPhotosExtensions();
var filename= fileName.ToLower();
bool isThere = false;
foreach(var item in list)
{
if (filename.EndsWith(item))
{
isThere = true;
break;
}
}
return isThere;
}
public static bool IsRecognisedImageFile(string fileName)
{
string targetExtension = System.IO.Path.GetExtension(fileName);
if (String.IsNullOrEmpty(targetExtension))
{
return false;
}
var recognisedImageExtensions = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders().SelectMany(codec => codec.FilenameExtension.ToLowerInvariant().Split(';'));
targetExtension = "*" + targetExtension.ToLowerInvariant();
return recognisedImageExtensions.Contains(targetExtension);
}
using (Stream stream = File.OpenRead(file))
{
try
{
using (Image sourceImage = Image.FromStream(stream, false, false))
{
}
}
catch (Exception x)
{
if (x.Message.Contains("not valid"))
{
Console.Write("This is not a Image.");
}
}
}