locked
Wrong contentType for StorageItemThumbnail

    Question

  • Using file.getThumbnailAsync(ThumbnailMode.singleItem, 140), I request a thumbnail for this image:  (by Yusuke Kamiyamane)

    The StorageItemThumbnail I get back has the contentType property set to 'image/jpeg'. However, the stream I get using getInputStreamAt() contains a PNG image, starting with the PNG magic number 8950 4e47 0d0a 1a0a.

    Is this a bug or am I using it wrong?


    • Edited by gdoo Wednesday, July 18, 2012 8:26 AM
    Wednesday, July 18, 2012 8:25 AM

Answers

  • Hi gdoo,

    You are using the API correctly. However, it seems that there is a bug in this API where images in a format that supports transparency (such as png / tif / gif) return a thumbnail that is identified as "image/jpeg" but is actually PNG. For now, please assume this is a bug; I will investigate more and will let you know if I find otherwise.

    Thanks for reporting this!

    Cheers,

    Marc

    • Marked as answer by gdoo Tuesday, July 31, 2012 7:01 AM
    Tuesday, July 31, 2012 12:12 AM

All replies

  • Sometimes I wonder what goes on in the developers head when they implement something like this.

    You request a thumbnail for a PNG image and get back a thumbnail in... BMP format.

    And beside that, the contentType of the Thumbnail object is wrong most of the time. It says "image/jpeg" when in fact the content stream contains a BMP.

    Wednesday, July 18, 2012 10:54 AM
  • Hi Phil,

    Do you have a repro of the stream type being incorrect?  Did you have a specific question?

    -Jeff


    Jeff Sanders (MSFT)

    Wednesday, July 18, 2012 2:34 PM
    Moderator
  • The question was "Why are system thumbnails of PNGs BMPs", similar to this one: http://social.msdn.microsoft.com/Forums/en-US/winappswithhtml5/thread/e55eb0a4-d72c-4f99-86a2-8d21e5759b5a
    Wednesday, July 18, 2012 3:03 PM
  • can you paste you code here?

    Why you want to get this picture's thumbnail? I think it's small enough..

    Thursday, July 19, 2012 1:15 PM
  • Right now I don't have the time to create a sample application reproducing the problem. I'm just getting the thumbnail, straight forward, and peek into the thumbnail data stream like this:

    Windows.Storage.ApplicationData.current.localFolder.getFileAsync('currency.png')
      .then(function (file) {
        return file.getThumbnailAsync(file);
      }).then(function (thumbnail) {
        var reader = new Windows.Storage.Streams.DataReader(thumbnail.getInputStreamAt(0));
        reader.loadAsync(2).then(function (actualSize) {
          var array = new Array(actualSize);
          reader.readBytes(array);
          reader.close();
    
          console.log(thumbnail.contentType);
          console.log(array[0] === 0xff, array[1] === 0xd8);
        });
      });
    })

    The contentType is 'image/jpeg', but the first two bytes do not match the JPEG magic number. In this case they match 0x89 and 0x50, the PNG magic number.

    I get wrong content types for other images too, this one is just an example. I've had PNG, BMP and JPG thumbnails, but the contentType always said 'image/jpeg'.

    • Edited by gdoo Thursday, July 19, 2012 1:43 PM
    Thursday, July 19, 2012 1:26 PM
  • Hi gdoo,

    You are using the API correctly. However, it seems that there is a bug in this API where images in a format that supports transparency (such as png / tif / gif) return a thumbnail that is identified as "image/jpeg" but is actually PNG. For now, please assume this is a bug; I will investigate more and will let you know if I find otherwise.

    Thanks for reporting this!

    Cheers,

    Marc

    • Marked as answer by gdoo Tuesday, July 31, 2012 7:01 AM
    Tuesday, July 31, 2012 12:12 AM
  • Hi Phil,

    The format of a thumbnail is independent of the format of the original image that the thumbnail was generated from. Generally, for small images a bitmap thumbnail is used to reduce decoding time and make it faster for apps to display the thumbnail. For large images, the thumbnail is compressed as jpeg to save disk space. Therefore, if you have a very large bmp image, its thumbnail is likely to be returned as a jpeg. This is by design.

    The issue here is that the thumbnail stream is mislabeled as "jpeg" when it is in fact "png" for transparent images. We are looking into this.

    Cheers,

    Marc

    Tuesday, July 31, 2012 12:17 AM
  • Thanks guys for clearing this up and filing the bugreport.
    Tuesday, July 31, 2012 7:23 AM
  • One thing that would be helpful for us as we look into this is understanding the use case where encountering this issue would be problematic. We expect the common usage of the API is to pass the thumbnail stream to a piece of code that detects the image format via the headers rather than relying on the ContentType property. Are there cases where the ContentType would be used instead, which would cause problems?

    Thanks!

    Marc

    Tuesday, July 31, 2012 6:40 PM
  • Marc, try setting a BMP thumbnail objectURL to an img.src property. It does not work, if the extension is not .bmp but jpg (as detected by the mime type). So we are currently indeed inspecting the thumbnail stream and set the proper extension. This works with .jpg that are .png and vice versa though. 
    Tuesday, July 31, 2012 8:39 PM
  • "... For large images, the thumbnail is compressed as jpeg to save disk space...."

    I don't think this is working as described. 

    I am seeing really large BMP format thumbnails returned.  I see it on several builds, including RTM.

    As an example, I have a 7Megapixel JPEG images, 1.6MBytes compressed.  I use the getThumbnailAsync call to generate an intermediate size image of approx 900x500.  The image returned by the API has a content type of BMP and is 2MBytes.  I'm sure it would JPEG compress to something much smaller.

    One omission from the API is a way to specify the quality of the JPEG encoding.  That is a factor that can control how small a JPEG format version would be.

    Friday, September 7, 2012 6:07 PM
  • One thing that would be helpful for us as we look into this is understanding the use case where encountering this issue would be problematic. We expect the common usage of the API is to pass the thumbnail stream to a piece of code that detects the image format via the headers rather than relying on the ContentType property. Are there cases where the ContentType would be used instead, which would cause problems?

    Thanks!

    Marc

    My use case is actually that I want to go through a folder of images (various sizes) and use the API to generate a set of scaled images all the same size.  I would actually like to always get JPEG - smaller, less space on disk, less bandwidth to stream over wifi, etc.  Failing a consistent (jpeg) content type, I expect to use the contentType property on the thumbnail object to select an appropriate extension when saving the image to disk.

    Friday, September 7, 2012 6:12 PM