I need a performant way to extract a thumbnail from a jpg-file without reading the whole file.
I wrote this method, which should work well - but it doesn't. The new file can not be read. Where is my mistake?
public static System.Drawing.Image GetThumbnail(string Image)
{
try
{
List<byte> image = new List<byte>();
byte[] _startToken = new byte[2] { 0xFF, 0xD8 }; //JPEG Start
byte[] _endToken = new byte[2] { 0xFF, 0xD9 }; //JPEG End
byte[] buff = new byte[2];
FileStream fs = new FileStream(Image, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
while (br.BaseStream.Position < br.BaseStream.Length)
{
byte bCurrent = br.ReadByte();
buff[0] = buff[1];
buff[1] = bCurrent;
if (Enumerable.SequenceEqual(buff, _startToken))
{
image.Clear();
image.AddRange(buff);
};
if (Enumerable.SequenceEqual(buff, _endToken))
{
break;
};
image.Add(bCurrent);
}
return (Bitmap)((new ImageConverter()).ConvertFrom(image.ToArray()));
}
catch
{
return null;
}
}
The whole JPEG file is inside the FFD8 - FFD9 bytes, not just the thumbnail so the code you've got there would copy the whole file. If you check the exact sizes of image.jpg and thumbnail.jpg you should see this.
However, because of the Image.Clear
you are losing the first byte and then the break
causes you to lose the last one.
You will need to actually parse the file according to the JPEG structure to reliably extract the thumbnail. I haven't used it but you may find it easier to adopt an existing library.