我想知道在加載字節數組後,是否有廉價的方式來獲取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