有没有办法在不必从字节中加载整个Image
对象的情况下获取图像的大小?
我现在这样做:
private Size GetImageSize(byte[] data)
{
using(Stream dataStream = new MemoryStream(data))
using(Image image = Image.FromStream(dataStream))
return image.Size;
}
但正如您所看到的,我正在创建一个新的MemoryStream
并复制所有图像数据,浪费空间,只是为了获得图像的大小。
答案 0 :(得分:0)
我认为您的代码是正确的方法,只需使用Image.FromStream Method (Stream, Boolean, Boolean)重载就可以跳过像这样的图像数据验证
static Size GetImageSize(byte[] data)
{
using(var dataStream = new MemoryStream(data))
using(var image = Image.FromStream(dataStream, false, false))
return image.Size;
}
但正如您所看到的,我正在创建一个新的MemoryStream并复制所有图像数据,浪费空间,只是为了获得图像的大小。
首先,使用的MemoryStream
构造函数不会复制任何数据,只是创建传递的Stream
的{{1}}包装器(视图)。
其次,虽然不能保证,但您可以依靠GDI +图像优化延迟数据处理/缓冲区分配,并略微传递[]byte
。
这是一个代码,可用于尝试查看正在进行的操作:
validateImageData=false
您可以在public struct ReadInfo
{
public long Position;
public int Count;
public override string ToString() { return "Pos: " + Position + " Count: " + Count; }
}
class TrackingMemoryStream : MemoryStream
{
public TrackingMemoryStream(byte[] buffer) : base(buffer) { }
public int TotalReadCount;
public List<ReadInfo> ReadInfo = new List<ReadInfo>();
public override int Read(byte[] buffer, int offset, int count)
{
var info = new ReadInfo { Position = Position };
info.Count = base.Read(buffer, offset, count);
ReadInfo.Add(info);
TotalReadCount += info.Count;
return info.Count;
}
}
static Size GetImageSize(byte[] data)
{
using (var dataStream = new TrackingMemoryStream(data))
using (var image = Image.FromStream(dataStream, false, false))
{
var size = image.Size;
return size;
}
}
行放置一个断点并检查dataStream跟踪信息。根据解码器(格式),您将看到不同的信息,但无论如何,与数据大小相比,存在非常小的块读取。当然,不能保证用于保存整个图像像素数据的内部缓冲区尚未被分配,但是很有可能被延迟。请注意,如果在调试器中展开return size;
变量,您将看到非常不同的跟踪流信息,因此此时很可能已经分配了像素数据缓冲区。
总而言之,在这种情况下,我会依赖解码器来正确获取我需要的信息,而不会关心内存分配。