[Windows 8] How to rescale an image in a Background task ?

May 7th, 2012 | Posted by Tom in .NET | HTML5 | Windows 8 | WinJS | Read: 2,595

In one of his blog post (here or here, for the French version), the Windows 8 Development Master David Catuhe explained how to generate and to rescale a new picture for a tile (secondary or not).

This is very useful if you’re not able to modify the service delivering the images to rescale them automatically. Its technique need you to use an Image HTML element and, unfortunately, you’re not allowed to use graphical components in a Windows 8 background task.

So here is the version I propose, which is quite different. First, I use a Promise when David’s version use an callback parameter. Then, I don’t use an Image element but I take advantage of the BitmapTransform class to perform a transformation (scale, rotation, etc.) on the image, accessed using the BitmapDecoder:

function rescaleImage2(src, destinationWidth, destinationHeight, localfilename) {

    return new WinJS.Promise(function (complete, error, progress) {

        var Imaging = Windows.Graphics.Imaging;

 

        WinJS.xhr({ url: src, responseType: “blob” }).then(function (request) {

            var imageStream = request.response;

 

            var fileName = new Date().getTime() + “_” + parseUri(src).file

 

            Windows.Storage.ApplicationData.current.localFolder.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.replaceExisting).then(function (rootFile) {

                rootFile.openAsync(Windows.Storage.FileAccessMode.readWrite).then(function (stream) {

                    Windows.Storage.Streams.RandomAccessStream.copyAsync(imageStream.msDetachStream(), stream).then(function () {

                        stream.flushAsync().then(function () {

                            stream.close();

                                     Windows.Storage.ApplicationData.current.localFolder.getFileAsync(fileName).then(function(file){

                            file.openReadAsync().then(function (stream) {

                                Imaging.BitmapDecoder.createAsync(stream).then(function (bd) {

                                    var transform = new Windows.Graphics.Imaging.BitmapTransform();

                                    transform.scaledHeight = destinationHeight;

                                    transform.scaledWidth = destinationWidth;

 

                                    bd.getPixelDataAsync(Imaging.BitmapPixelFormat.rgba8, Imaging.BitmapAlphaMode.straight, transform, Imaging.ExifOrientationMode.respectExifOrientation, Imaging.ColorManagementMode.doNotColorManage).then(function (pdp) {

                                        var pixelData = pdp.detachPixelData();

                                       Windows.Storage.ApplicationData.current.localFolder.createFileAsync(localfilename, Windows.Storage.CreationCollisionOption.replaceExisting).then(function (file) {

           file.openAsync(Windows.Storage.FileAccessMode.readWrite).then(function (stream){

                                                                 Imaging.BitmapEncoder.createAsync(Imaging.BitmapEncoder.pngEncoderId, stream).then(function (encoder) {

               encoder.setPixelData(Imaging.BitmapPixelFormat.rgba8, Imaging.BitmapAlphaMode.straight, destinationWidth, destinationHeight, 96, 96, pixelData);

 

               encoder.flushAsync().then(function () {

                   stream.flushAsync().then(function () {

                       stream.close();

                       rootFile.deleteAsync().done(function () {

                           if (complete)

                               complete(“ms-appdata:///local/” + localfilename.replace(“\\”, “/”));

                                                            });

                                                        });

                                                    });

                                                });

                                             });

                                         });

                                      });

                                  });

                              });

                          });

                      });

                  });

              });

          });

      });

    });

}

The code is also available, in a more readable format, here (thanks http://codepaste.net !)

As always, feel free to use it, comment, it, etc.

 

Happy coding!

You can follow any responses to this entry through the RSS 2.0 You can leave a response, or trackback.

2 Responses

Add Comment Register



Leave a Reply