我想知道在加载一个字节数组后是否有一种廉价的方法来获取JPEG的宽度和高度。
我知道JpegBitmapDecoder
可以获得JPEG的像素宽度和高度,但它也会加载很多信息,我认为这是一项昂贵的操作。
是否有其他方法可以从字节数组中获取宽度和高度而不进行解码?
由于
答案 0 :(得分:17)
由于某种未知的原因,我没有去睡觉,而是开始研究这个问题。
这里有一些代码可以用最少的存储空间来解决这个问题。
void Main()
{
var filePath=@"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);
}
}
答案 1 :(得分:2)
几年前我读过关于它的CodeProject文章:) 我不是百分之百确定它有多好,并且没有自己测试过,但作者对此非常满意;他的测试也证明它比阅读整个图像要快得多,正如你所期望的那样:)
这是文章本身..希望这是你需要的!
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