23.01.2018 Views

MICROSOFT_PRESS_EBOOK_PROGRAMMING_WINDOWS_8_APPS_WITH_HTML_CSS_AND_JAVASCRIPT_PDF

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

When we click Grayscale we enter the setGrayscale handler where the interesting work happens. We<br />

call StorageFile.openReadAsync to get a stream, call BitmapDecoder.createAsync with that to obtain a<br />

decoder, cache some details from the decoder in a local object (encoding), and call BitmapDecoder.-<br />

getPixelDataAsync and copy those pixels to a canvas (and only three chained async operations here!):<br />

var Imaging = Windows.Graphics.Imaging; //Shortcut<br />

var imageFile;<br />

//Saved from the file picker<br />

var decoder;<br />

//Saved from BitmapDecoder.createAsync<br />

var encoding = {};<br />

//To cache some details from the decoder<br />

function setGrayscale() {<br />

//Decode the image file into pixel data for a canvas<br />

//Get an input stream for the file (StorageFile object saved from opening)<br />

imageFile.openReadAsync().then(function (stream) {<br />

//Create a decoder using static createAsync method and the file stream<br />

return Imaging.BitmapDecoder.createAsync(stream);<br />

}).then(function (decoderArg) {<br />

decoder = decoderArg;<br />

//Configure the decoder if desired. Default is BitmapPixelFormat.rgba8 and<br />

//BitmapAlphaMode.ignore. The parameterized version of getPixelDataAsync can also<br />

//control transform, ExifOrientationMode, and ColorManagementMode if needed.<br />

//Cache these settings for encoding later<br />

encoding.dpiX = decoder.dpiX;<br />

encoding.dpiY = decoder.dpiY;<br />

encoding.pixelFormat = decoder.bitmapPixelFormat;<br />

encoding.alphaMode = decoder.bitmapAlphaMode;<br />

encoding.width = decoder.pixelWidth;<br />

encoding.height = decoder.pixelHeight;<br />

}<br />

return decoder.getPixelDataAsync();<br />

}).done(function (pixelProvider) {<br />

//detachPixelData gets the actual bits (array can't be returned from<br />

//an async operation)<br />

copyGrayscaleToCanvas(pixelProvider.detachPixelData(),<br />

decoder.pixelWidth, decoder.pixelHeight);<br />

});<br />

The decoder’s getPixelDataAsync method comes in two forms. The simple form, shown here,<br />

decodes using defaults. The full-control version lets you specify other parameters, as explained in the<br />

code comments above. A common use of this is doing a transform using a Windows.Graphics.-<br />

Imaging.BitmapTransform object (as mentioned before), which accommodates scaling (with different<br />

interpolation modes), rotation (90-degree increments), cropping, and flipping.<br />

Either way, what you get back from the getPixelDataAsync is not the actual pixel array, because of a<br />

limitation in the WinRT language projection mechanism whereby an asynchronous operation cannot<br />

return an array. Instead, the operation returns a PixelDataProvider object whose singular<br />

super-exciting synchronous method called detachPixelData gives you the array you want. (And that<br />

444

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!