I presented a way to upload multiple images in my previous post. Sometime we need to manipulate the images first, such as resizing, compress, then do the upload. There's a few ways to do such job using Windows 8 JavaScript. The easiest one is use HTML5 canvas:
// Convert image dataUri format to blob format
function dataURItoBlob(dataURI) {
var byteString = atob(dataURI.split(',')[1]);
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
var byteArray = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
byteArray[i] = byteString.charCodeAt(i) & 0xff;
}
return new Blob([byteArray], { type: mimeString });
}
// Use HTML5 canvas to resize and compress an image
function resizeAndCompressImageToBlob(image, length, quality) {
var isLandScape = image.naturalWidth > image.naturalHeight;
var width = isLandScape ? length : parseInt((length / image.naturalHeight) * image.naturalWidth)
var heigh = isLandScape ? parseInt((width / image.naturalWidth) * image.naturalHeight) : length;
var cvs = document.createElement('canvas');
cvs.width = width;
cvs.height = heigh;
cvs.getContext("2d").drawImage(image, 0, 0, width, heigh);
var dataUri = cvs.toDataURL("image/jpeg", quality);
var imgBlob = dataURItoBlob(dataUri);
return imgBlob;
}
// Load image asynchronously
function loadImageAsync(src) {
return new WinJS.Promise(function (c, e, p) {
var img = new Image();
img.src = src;
img.addEventListener("load", function () {
c(img);
});
});
}
function uploadMultipleImages(url, formFields) {
return new WinJS.Promise(function (c, e, p) {
var dataToSend = new FormData();
var filePicker = new Windows.Storage.Pickers.FileOpenPicker();
filePicker.fileTypeFilter.replaceAll([".jpg", ".jpeg"]);
filePicker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.picturesLibrary;
filePicker.pickMultipleFilesAsync().then(function (files) {
if (files.length === 0) {
console.log("No file selected");
return;
}
if (formFields && formFields.length > 0) {
formFields.forEach(function (formField) {
for (var key in formField) {
dataToSend.append(key, formField[key]); // Add field value
}
});
}
var imgPromises = []; // Promises for all image loading
files.forEach(function (file, index) {
var objectUrl = URL.createObjectURL(file, { oneTimeOnly: true });
var loadImage = loadImageAsync(objectUrl, file.name);
imgPromises.push(loadImage);
});
// Wait for all async calls completion
WinJS.Promise.join(imgPromises).then(function (data) {
var savePromieses = [];
for (var i = 0; i < data.length; i++) {
var imageBlob = resizeAndCompressImageToBlob(data[i], 1200, 0.8);
dataToSend.append(files[i].name, imageBlob, files[i].name);
}
var options = { url: url, type: "POST", data: dataToSend };
WinJS.xhr(options).then(function (response) {
c(response);
},
function (xhrError) {
e(xhrError);
});
},
function (joinError) {
e(joinError);
});
});
});
}