3

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;
    }
}
fubo
  • 44,811
  • 17
  • 103
  • 137
  • libexif is great handling exif in native code. – kobigurk Jul 16 '14 at 12:24
  • The JPEG standard is a bit more complicated that what your code can handle. There are "chunks" that are marked with a size. A chunk could be a comment, EXIF, thumbnail, or other things. A chunk is marked with a size. The thumbnail data can come in different formats, and is completely optional. – David Crowell Jul 16 '14 at 12:24
  • Ok good to know - i just waned to have a short snipped like this without that much overhead and it works with the images from my nikon. – fubo Jul 16 '14 at 12:31
  • @David Crowell - i updated the code for other formats and for the case of not existing – fubo Jul 16 '14 at 13:15

1 Answers1

3

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.

Andy Jones
  • 584
  • 2
  • 14