我想知道在加载字节数组后,是否有廉价的方式来获取JPEG的宽度和高度。从JPEG解析图像大小
我知道JpegBitmapDecoder
可以获得JPEG的像素宽度和高度,但它也加载了很多信息,我认为这会是一个昂贵的操作。
是否有另一种方法从字节数组中获取宽度和高度而不解码?
感谢
我想知道在加载字节数组后,是否有廉价的方式来获取JPEG的宽度和高度。从JPEG解析图像大小
我知道JpegBitmapDecoder
可以获得JPEG的像素宽度和高度,但它也加载了很多信息,我认为这会是一个昂贵的操作。
是否有另一种方法从字节数组中获取宽度和高度而不解码?
感谢
对于一些未知的原因,而不是去睡觉,我去了这方面的工作。
下面是一些代码,以最小的存储需求解决这个问题。
void Main()
{
var [email protected]"path\to\my.jpg";
var bytes=File.ReadAllBytes(filePath);
var dimensions=GetJpegDimensions(bytes);
//or
//var dimensions=GetJpegDimensions(filePath);
Console.WriteLine(dimensions);
}
public static Dimensions GetJpegDimensions(byte[] bytes)
{
using(var ms=new MemoryStream(bytes))
{
return GetJpegDimensions(ms);
}
}
public static Dimensions GetJpegDimensions(string filePath)
{
using(var fs=File.OpenRead(filePath))
{
return GetJpegDimensions(fs);
}
}
public static Dimensions GetJpegDimensions(Stream fs)
{
if(!fs.CanSeek) throw new ArgumentException("Stream must be seekable");
long blockStart;
var buf = new byte[4];
fs.Read(buf, 0, 4);
if(buf.SequenceEqual(new byte[]{0xff, 0xd8, 0xff, 0xe0}))
{
blockStart = fs.Position;
fs.Read(buf, 0, 2);
var blockLength = ((buf[0] << 8) + buf[1]);
fs.Read(buf, 0, 4);
if(Encoding.ASCII.GetString(buf, 0, 4) == "JFIF"
&& fs.ReadByte() == 0)
{
blockStart += blockLength;
while(blockStart < fs.Length)
{
fs.Position = blockStart;
fs.Read(buf, 0, 4);
blockLength = ((buf[2] << 8) + buf[3]);
if(blockLength >= 7 && buf[0] == 0xff && buf[1] == 0xc0)
{
fs.Position += 1;
fs.Read(buf, 0, 4);
var height = (buf[0] << 8) + buf[1];
var width = (buf[2] << 8) + buf[3];
return new Dimensions(width, height);
}
blockStart += blockLength + 2;
}
}
}
return null;
}
public class Dimensions
{
private readonly int width;
private readonly int height;
public Dimensions(int width, int height)
{
this.width = width;
this.height = height;
}
public int Width
{
get{return width;}
}
public int Height
{
get{return height;}
}
public override string ToString()
{
return string.Format("width:{0}, height:{1}", Width, Height);
}
}
我已经阅读了CodeProject上的文章一对夫妇几年前:) 我不是100%肯定它是多么的好,没有测试它自己,但笔者的绝对幸福用它;还有他的测试证明它比阅读整个图像更快,正如你所期望的那样:)
这里是文章本身..希望这是你需要的! http://www.codeproject.com/KB/cs/ReadingImageHeaders.aspx
的一段代码,你要寻找的开始约在这里:
http://www.codeproject.com/KB/cs/ReadingImageHeaders.aspx#premain3
UPD:同时,检查意见的底部。特别是最后一个(顶部)一个有..可能是有用的使其更通用
而且,更深入,先进的信息可以在这里捡到:http://www.codeproject.com/KB/graphics/iptc.aspx
+1我想这就意味着要超越并提供一个答案! – BrokenGlass 2010-11-04 01:34:34
我试过了,但是序列以0xe1而不是0xe0结尾,并且ASCII编码以EXIF形式出现。我猜这是一种不同类型的JPEG图像,但这意味着此解决方案不适用于所有JPEG图像。 – Grungondola 2016-05-18 14:43:35
@Grungondola你是对的......有一大堆'.jpg'文件不适用于上面的代码。经过广泛的研究,我可以说到目前为止提取图像元数据的最好方法是使用[imagemagick](http://www.imagemagick.org/script/binary-releases.php)...为了提供最好的隔离在托管过程中,我们用'System.Diagnostics.Process'调用独立的'magick.exe标识'并从流程的标准输出解析元数据。非常防弹。 – spender 2016-05-18 22:14:36