I think your code is the correct way to go, just use the Image.FromStream Method (Stream, Boolean, Boolean) overload in order to skip image data validation like this
static Size GetImageSize(byte[] data)
{
using(var dataStream = new MemoryStream(data))
using(var image = Image.FromStream(dataStream, false, false))
return image.Size;
}
But as you can see I am creating a new MemoryStream and copying all the image data, wasting space, just to get the size of the image.
First, the MemoryStream
constructor used does not copy any data, but just creates a Stream
wrapper (view) of the passed []byte
.
Second, although not guaranteed, you can rely on GDI+ image optimizations of delayed data processing/buffer allocation with a little hint of passing validateImageData=false
.
Here is a code that can be used to try to see what's going on:
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;
}
}
You can put a breakpoint at return size;
line and examine the dataStream tracking info. Depending of the decoder (format), you'll see a different information, but in any case there are quite small chunk reads compared to the data size. Of course there is no guarantee that the internal buffer for holding the whole image pixel data has not been allocated, but there is a big chance of that being deferred. Note that if you expand the image
variable in the debugger, you'll see a very different tracking stream information, so at that point most probably the pixel data buffer has been allocated.
To conclude, in this case I would rely on decoders to get correctly the information I need and will not be concerned about memory allocation.