I am working on a FineUploader implementation. Special request is to create thumbnails on the fly client-side and then upload those with the original image-upload.
I have an implementation that works on FF, but does not seem to work on iOs. It looks like so:
var uploader = new qq.FineUploaderBasic({
button: document.getElementById(buttonID),
request: {
endpoint: '/up/load/a/' + $('section#ajax-viewport').data('albumid')
},
callbacks: {
onSubmit: function(id, fileName) {
// getFile obtains the file being uploaded
file = this.getFile(id);
// create a thumbnail & upload it:
ThumbDown(file, id, 200, fileName);
},
}
})
This code calls a function:
function ThumbDown(file, id, dimension, fileName) {
var reader = new FileReader();
reader.onload = function(e) {
var img = document.createElement("img");
img.onload = function (ev) {
var thumbnailDimensions; // object holding width & height of thumbnail
var c=document.getElementById("canvas-for-thumbnails"); // must be a <canvas> element
var ctx=c.getContext("2d");
// set thumbnail dimensions of canvas:
thumbnailDimensions = calcThumbnailDimension (img.width, img.height, dimension )
c.width = thumbnailDimensions.width;
c.height = thumbnailDimensions.height;
var ctx = c.getContext("2d");
ctx.drawImage(img, 0, 0, c.width, c.height);
uploadThumbnail(c.toDataURL('image/jpeg'), //a base64 encoded representation of the image
id,
fileName); // we need filename to combine with mother-image on the server
};
img.src = e.target.result;
}
reader.readAsDataURL(file);
} // end function
Finally the Thumbnail is uploaded with a dumb ajax-call:
function uploadThumbnail (base64encodedString, id, fileName) {
$.post('/up/thumb',
{
img : base64encodedString,
id: id,
fileName: fileName
},
function(data) {});
}
My questions:
1) Currently I have two uploads: one for mother-image and another for thumbnail. I would like to combine this in one FineUploader call. However, I do not see a way to do this, due to the asynchronous nature of my thumbnail creation.
Am I missing something? Is this possible to reduce this to one FineUploader call?
2) This code uploads the thumbnails as a base64 encoded string. I would like to upload the thumbnail as an image (or as a blob
?). Perhaps by following this recipe of Jeremy Banks. Would that work with FineUploader?
3) Are there other options/methods of FineUploader that I have missed but I should be using?
Any help is, as always, greatly appreciated.
So, it is already trivial to upload the original image. Fine Uploader takes care of that for you. If I understand correctly, you want to also upload a scaled version of the image (which you have already generated). I suggest you take the image you have drawn onto the canvas and convert it to a Blob
. Then, you can submit this Blob
directly to Fine Uploader, where it will upload it for you.
For example, change the value of uploadThumbnail
to this:
function uploadThumbnail(thumbnailDataUri, id, filename) {
var imageBlob = getImageBlob(thumbnailDataUri, "image/jpeg"),
blobData = {
name: filename,
blob: imageBlob
};
// This will instruct Fine Uploader to upload the scaled image
uploader.addBlobs(blobData);
}
function getImageBlob(dataUri, type) {
var binary = atob(dataUri.split(',')[1]),
array = [];
for(var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], {type: type});
}
Note: the getImageBlob
function was adapted from this Stack Overflow answer. If this works for you, be sure to upvote the answer I've linked to.
A Blob
is pretty much a File
without a name
property. Your server-side code will handle the upload of a Blob
pretty much the same way as it does a File
or form submit containing a <input type="file">
form field. The only noticeable difference to your server will be the filename parameter value in the Content-Disposition header of the multipart boundary containing the file. To put it another way, your server may think the image is named "blob" or perhaps some other generic name, due to the way most browsers generate multipart encoded requests that contain Blob
objects. Fine Uploader should be able to get around that by explicitly specifying a file name for the browser to include in blob's Content-Disposition header, but this ability does not have wide browser support. Fine Uploader gets around this limitation, to some degree, by including a "qqfilename" parameter with the request containing the actual name of the Blob
.
The plan is to add native support for thumbnail previews to Fine Uploader. This is covered in feature requests #868 and #896. There are other related feature requests open, such as image rotation and validation related to images. These features and other image-related features will likely be added to Fine Uploader in the very near future. Be sure to comment on the existing feature requests or add additional requests if you'd like.