有没有办法找出图像的ContentType只来自原始字节?
目前我有一个数据库列,只存储byte [],我用它来在网页上显示图像。
MemoryStream ms = new MemoryStream(imageBytes);
Image image = Image.FromStream(ms);
image.Save(context.HttpContext.Response.OutputStream, <--ContentType-->);
我当然可以将ContentType保存在表格的另一列中,但只是想知道是否还有另一种方式,例如也许.Net有办法询问数据以获得类型。
答案 0 :(得分:15)
答案 1 :(得分:14)
文件/魔术签名是要走的路。以下是代码的工作版本。
参考:Stackoverflow - Getting image dimensions without reading the entire file
ImageFormat contentType = ImageHelper.GetContentType(this.imageBytes);
MemoryStream ms = new MemoryStream(this.imageBytes);
Image image = Image.FromStream(ms);
image.Save(context.HttpContext.Response.OutputStream, contentType);
然后是助手类:
public static class ImageHelper
{
public static ImageFormat GetContentType(byte[] imageBytes)
{
MemoryStream ms = new MemoryStream(imageBytes);
using (BinaryReader br = new BinaryReader(ms))
{
int maxMagicBytesLength = imageFormatDecoders.Keys.OrderByDescending(x => x.Length).First().Length;
byte[] magicBytes = new byte[maxMagicBytesLength];
for (int i = 0; i < maxMagicBytesLength; i += 1)
{
magicBytes[i] = br.ReadByte();
foreach (var kvPair in imageFormatDecoders)
{
if (magicBytes.StartsWith(kvPair.Key))
{
return kvPair.Value;
}
}
}
throw new ArgumentException("Could not recognise image format", "binaryReader");
}
}
private static bool StartsWith(this byte[] thisBytes, byte[] thatBytes)
{
for (int i = 0; i < thatBytes.Length; i += 1)
{
if (thisBytes[i] != thatBytes[i])
{
return false;
}
}
return true;
}
private static Dictionary<byte[], ImageFormat> imageFormatDecoders = new Dictionary<byte[], ImageFormat>()
{
{ new byte[]{ 0x42, 0x4D }, ImageFormat.Bmp},
{ new byte[]{ 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 }, ImageFormat.Gif },
{ new byte[]{ 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 }, ImageFormat.Gif },
{ new byte[]{ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }, ImageFormat.Png },
{ new byte[]{ 0xff, 0xd8 }, ImageFormat.Jpeg },
};
答案 2 :(得分:6)
这对我有用,ms
是记忆流。缺点是它必须加载图像。
Dim fmt As System.Drawing.Imaging.ImageFormat
Dim content As String
Using bmp As New Drawing.Bitmap(ms)
fmt = bmp.RawFormat
End Using
Select Case fmt.Guid
Case Drawing.Imaging.ImageFormat.Bmp.Guid
content = "image/x-ms-bmp"
Case Drawing.Imaging.ImageFormat.Jpeg.Guid
content = "image/jpeg"
Case Drawing.Imaging.ImageFormat.Gif.Guid
content = "image/gif"
Case Drawing.Imaging.ImageFormat.Png.Guid
content = "image/png"
Case Else
content = "application/octet-stream"
End Select
答案 3 :(得分:2)
使用Linq重写了Nick Clarke的方法:
public class Program
{
public static void Main(string[] args)
{
byte[] byteArray = File.ReadAllBytes(@"C:/users/Alexander/image.jpg");
ImagePartType type = byteArray.GetImageType();
}
}
public static class ImageHelper
{
public static ImagePartType GetImageType(this byte[] imageBytes)
{
foreach(var imageType in imageFormatDecoders)
{
if (imageType.Key.SequenceEqual(imageBytes.Take(imageType.Key.Length)))
return imageType.Value;
}
throw new ArgumentException("Imagetype is unknown!");
}
private static Dictionary<byte[], ImagePartType> imageFormatDecoders
= new Dictionary<byte[], ImagePartType>()
{
{ new byte[]{ 0x42, 0x4D }, ImagePartType.Bmp},
{ new byte[]{ 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 }, ImagePartType.Gif },
{ new byte[]{ 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 }, ImagePartType.Gif },
{ new byte[]{ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }, ImagePartType.Png },
{ new byte[]{ 0xff, 0xd8 }, ImagePartType.Jpeg }
};
}
我使用ImagePartType
,因为我目前正在使用Open XML SDK,但只需更改字典中的类型:)
答案 4 :(得分:1)
从内置的流中检测内容类型没有标准方法。您可以通过读取前几个字节并尝试匹配格式来实现自己的算法,以便为某些well-known图像格式实现此目的。
答案 5 :(得分:0)
RawFormat
属性是否适合您?
MemoryStream ms = new MemoryStream(imageBytes);
Image image = Image.FromStream(ms);
image.Save(context.HttpContext.Response.OutputStream, image.RawFormat);