53856

resize image before upload via background transfer in winjs

Question:

I would like to resize an image picked from the gallery of the phone before uploading it via background transfer so far I have:-

filePicker.pickSingleFileAsync().then(function (file) { uploadSingleFileAsync(uri, file); }).done(null, displayException); function uploadSingleFileAsync(uri, file) { if (!file) { displayError("Error: No file selected."); return; } return file.getBasicPropertiesAsync().then(function (properties) { if (properties.size > maxUploadFileSize) { displayError("Selected file exceeds max. upload file size (" + (maxUploadFileSize / (1024 * 1024)) + " MB)."); return; } var upload = new UploadOperation(); //tried this to compress the file but it doesnt work obviously not right for the object //file = file.slice(0, Math.round(file.size / 2)); upload.start(uri, file); // Persist the upload operation in the global array. uploadOperations.push(upload); }); }

and the rest then uploads the file. I tried adding in .slice but it doesn't work (im guessing because file is an object rather than) and i'm not sure how to compress this type of file object. I can't seem to find any examples or advice on msdn or the windows dev forums, I can obviously resize the photos once they are on the server but I would rather users are not waiting longer than they have to for their files to upload.

Do I need to save the image before I can manipulate it? Any advice would be greatly appreciated!

<strong>**</strong> EDIT <strong><em>*</em></strong>

my upload singlefileasync now looks like:-

function uploadSingleFileAsync(uri, file) { if (!file) { displayError("Error: No file selected."); return; } return file.getBasicPropertiesAsync().then(function (properties) { if (properties.size > maxUploadFileSize) { displayError("Selected file exceeds max. upload file size (" + (maxUploadFileSize / (1024 * 1024)) + " MB)."); return; } // Exception number constants. These constants are defined using values from winerror.h, // and are compared against error.number in the exception handlers in this scenario. // This file format does not support the requested operation; for example, metadata or thumbnails. var WINCODEC_ERR_UNSUPPORTEDOPERATION = Helpers.convertHResultToNumber(0x88982F81); // This file format does not support the requested property/metadata query. var WINCODEC_ERR_PROPERTYNOTSUPPORTED = Helpers.convertHResultToNumber(0x88982F41); // There is no codec or component that can handle the requested operation; for example, encoding. var WINCODEC_ERR_COMPONENTNOTFOUND = Helpers.convertHResultToNumber(0x88982F50); // Keep objects in-scope across the lifetime of the scenario. var FileToken = ""; var DisplayWidthNonScaled = 0; var DisplayHeightNonScaled = 0; var ScaleFactor = 0; var UserRotation = 0; var ExifOrientation = 0; var DisableExifOrientation = false; // Namespace and API aliases var FutureAccess = Windows.Storage.AccessCache.StorageApplicationPermissions.futureAccessList; var LocalSettings = Windows.Storage.ApplicationData.current.localSettings.values; //FileToken = FutureAccess.add(file); FileToken = Windows.Storage.AccessCache.StorageApplicationPermissions.futureAccessList.add(file); id("myImage").src = window.URL.createObjectURL(file, { oneTimeOnly: true }); id("myImage").alt = file.name; // Use BitmapDecoder to attempt to read EXIF orientation and image dimensions. return loadSaveFileAsync(file) function resetPersistedState() { LocalSettings.remove("scenario2FileToken"); LocalSettings.remove("scenario2Scale"); LocalSettings.remove("scenario2Rotation"); } function resetSessionState() { // Variables width and height reflect rotation but not the scale factor. FileToken = ""; DisplayWidthNonScaled = 0; DisplayHeightNonScaled = 0; ScaleFactor = 1; UserRotation = Windows.Storage.FileProperties.PhotoOrientation.normal; ExifOrientation = Windows.Storage.FileProperties.PhotoOrientation.normal; DisableExifOrientation = false; } function loadSaveFileAsync(file) { // Keep data in-scope across multiple asynchronous methods. var inputStream; var outputStream; var encoderId; var pixels; var pixelFormat; var alphaMode; var dpiX; var dpiY; var outputFilename; var ScaleFactor = 0.5; new WinJS.Promise(function (comp, err, prog) { comp(); }).then(function () { // On Windows Phone, this call must be done within a WinJS Promise to correctly // handle exceptions, for example if the file is read-only. return FutureAccess.getFileAsync(FileToken); }).then(function (inputFile) { return inputFile.openAsync(Windows.Storage.FileAccessMode.read); }).then(function (stream) { inputStream = stream; return Windows.Graphics.Imaging.BitmapDecoder.createAsync(inputStream); }).then(function (decoder) { var transform = new Windows.Graphics.Imaging.BitmapTransform(); // Scaling occurs before flip/rotation, therefore use the original dimensions // (no orientation applied) as parameters for scaling. // Dimensions are rounded down by BitmapEncoder to the nearest integer. transform.scaledHeight = decoder.pixelHeight * ScaleFactor; transform.scaledWidth = decoder.pixelWidth * ScaleFactor; transform.rotation = Helpers.convertToBitmapRotation(UserRotation); // Fant is a relatively high quality interpolation mode. transform.interpolationMode = Windows.Graphics.Imaging.BitmapInterpolationMode.fant; // The BitmapDecoder indicates what pixel format and alpha mode best match the // natively stored image data. This can provide a performance and/or quality gain. pixelFormat = decoder.bitmapPixelFormat; alphaMode = decoder.bitmapAlphaMode; dpiX = decoder.dpiX; dpiY = decoder.dpiY; // Get pixel data from the decoder. We apply the user-requested transforms on the // decoded pixels to take advantage of potential optimizations in the decoder. return decoder.getPixelDataAsync( pixelFormat, alphaMode, transform, Windows.Graphics.Imaging.ExifOrientationMode.respectExifOrientation, Windows.Graphics.Imaging.ColorManagementMode.colorManageToSRgb ); }).then(function (pixelProvider) { pixels = pixelProvider.detachPixelData(); // The destination file was passed as an argument to loadSaveFileAsync(). outputFilename = file.name; switch (file.fileType) { case ".jpg": encoderId = Windows.Graphics.Imaging.BitmapEncoder.jpegEncoderId; break; case ".bmp": encoderId = Windows.Graphics.Imaging.BitmapEncoder.bmpEncoderId; break; case ".png": default: encoderId = Windows.Graphics.Imaging.BitmapEncoder.pngEncoderId; break; } return file.openAsync(Windows.Storage.FileAccessMode.readWrite); }).then(function (stream) { outputStream = stream; // BitmapEncoder expects an empty output stream; the user may have selected a // pre-existing file. outputStream.size = 0; return Windows.Graphics.Imaging.BitmapEncoder.createAsync(encoderId, outputStream); }).then(function (encoder) { // Write the pixel data onto the encoder. Note that we can't simply use the // BitmapTransform.ScaledWidth and ScaledHeight members as the user may have // requested a rotation (which is applied after scaling). encoder.setPixelData( pixelFormat, alphaMode, DisplayWidthNonScaled * ScaleFactor, DisplayHeightNonScaled * ScaleFactor, dpiX, dpiY, pixels ); return encoder.flushAsync(); }).then(function () { WinJS.log && WinJS.log("Successfully saved a copy: " + outputFilename, "sample", "status"); }, function (error) { WinJS.log && WinJS.log("Failed to update file: " + error.message, "sample", "error"); resetSessionState(); resetPersistedState(); }).then(function () { // Finally, close each stream to release any locks. inputStream && inputStream.close(); outputStream && outputStream.close(); }).then(function () { var upload = new UploadOperation(); upload.start(uri, file); // Persist the upload operation in the global array. uploadOperations.push(upload); }); }

But I am getting an error when I reach this line return<br /> file.openAsync(Windows.Storage.FileAccessMode.readWrite); saying that I do not have write access? How do I get write access or move it so that I can have write access?

Answer1:

To resize an image you can use the image encoding APIs in WinRT, namely that in Windows.Graphics.Imaging. I suggest you look at scenario 2 of the Simple Imaging Sample (<a href="http://code.msdn.microsoft.com/windowsapps/Simple-Imaging-Sample-a2dec2b0" rel="nofollow">http://code.msdn.microsoft.com/windowsapps/Simple-Imaging-Sample-a2dec2b0</a>) which shows how to do all manners of transforms on an image. Changing the dimensions is included there, so it'll just be a matter of chopping out the parts you don't need.

I have a discussion about all this in my free ebook, <a href="http://aka.ms/BrockschmidtBook2" rel="nofollow"><em>Programming Windows Store Apps with HTML, CSS, and JavaScript, 2nd Edition</em></a>, in Chapter 13, section "Image Manipulation and Encoding". In there I try to separate out the main steps in the process into something a little more digestible, and provide an additional sample.

The process of encoding can look rather involved (lots of chained promises), but it's quite straightforward and is exactly what an email program would do to reduce the size of attached images, for instance. In any case, you should end up with another StorageFile with a smaller image that you can then pass to the uploader. I would recommend using your Temporary app data for such files, and be sure to clean them up when the upload is complete.

Recommend

  • Loading an array from a .txt file? (Android)
  • XSL numbering at different levels
  • how can I use remove for this code?
  • Some data changes in the database. How can I trigger some C# code doing some work upon these changes
  • Notification for keyboard
  • In python, why does 0xbin() return False? [duplicate]
  • Memory error: numpy.genfromtxt()
  • How to use loop in Jquery to add table multiple times into div
  • jQuery Accordion Functionality panel opens when it shouldn't be opening
  • Do elements with “position: absolute;” behave as block-level elements?
  • globals() vs locals() mutability
  • Is it possible to print a function as a string in Python? [duplicate]
  • how do I Sort and organize data from csv file in php
  • What's the difference between list() and [] [duplicate]
  • Scapy sniff() in a class that subclassess threading.Thread()
  • navigator.notification.alert fires 4 alerts for 1 call on IOS - jquery mobile - phonegap 2.2.0
  • Adobe CQ5 regex that will reject an entire string if either of 2 different substrings are found with
  • How and where to install a module in python from github
  • PHP shell_exec running a shellscript with ssh
  • Lucene Query Boosting
  • Unpickling mid-stream (python)
  • Converting a PEM private key file to a JAVA PrivateKey Object
  • Data Type of Columns in a List - R
  • How to get or calculate size of Azure File/Share or Service
  • Where to save the local DB created for iphone app?
  • get passwords from chrome
  • Does the Azure table storage API cache results?
  • how to upload multiple files in c# windows application
  • C# - Serializing and deserializing static member
  • Sony Xperia Z Tablet not found by adb
  • Javascript convert timezone issue
  • How to model a transition system with SPIN
  • Why is the timeout on a windows udp receive socket always 500ms longer than set by SO_RCVTIMEO?
  • How do you join a server to an Active Directory (domain)?
  • Cant find why the layout is getting smaller
  • How to stop GridView from loading again when I press back button?
  • Bitwise OR returns boolean when one of operands is nil
  • sending mail using smtp is too slow
  • costura.fody for a dll that references another dll
  • Binding checkboxes to object values in AngularJs