JQuery file upload (RailsCasts #383): Upload multiple resolutions to S3 - jquery-file-upload

I am using the upload_helper described in RailsCasts episode #383 to directly upload files to AWS S3.
The following works for me, the image is re-sized to 800x600 and stored to S3.
jQuery ->
$('#fileupload').fileupload
processQueue: [
{
action: 'loadImage'
fileTypes: /^image\/(gif|jpeg|png)$/
maxFileSize: 20000000
}
{
action: 'resizeImage'
maxWidth: 800
maxHeight: 600
}
{ action: 'saveImage' }
]
add: (e, data) ->
$.blueimp.fileupload.prototype.options.add.call(this, e, data)
Now, what I want to do is also store a much smaller version as a thumbnail. I have the following code which seems to be working apart from the fact that its trying to upload both files to S3 using the same POST request.
$.blueimp.fileupload::processActions.duplicateImage = (data, options) ->
if data.canvas
data.files.push data.files[data.index]
data
jQuery ->
$('#fileupload').fileupload
processQueue: [
{
action: 'loadImage'
fileTypes: /^image\/(gif|jpeg|png)$/
maxFileSize: 20000000
}
{
action: 'resizeImage'
maxWidth: 800
maxHeight: 600
}
{ action: 'saveImage' }
{ action: 'duplicateImage' }
{
action: 'resizeImage'
maxWidth: 400
maxHeight: 300
}
{action: 'saveImage'}
]
add: (e, data) ->
$.blueimp.fileupload.prototype.options.add.call(this, e, data);
The error I am getting is as follows.
POST https://mybucket-uploads.s3.amazonaws.com/ 400 (Bad Request)
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>InvalidArgument</Code><Message>POST requires exactly one file upload per request.</Message><ArgumentName>file</ArgumentName><ArgumentValue>2</ArgumentValue><RequestId>F2D33882A6556810</RequestId><HostId>3DP7aHL4aR1ErG5eIWh2kgQUXbsrytBU2u/pdQO746X2njjWckUVZtivcIJoY9qYsOBN13TPbyU=</HostId></Error>
How can I get this to work?

Related

ionic 1.x : crop image

I have two buttons, the first one for browse image from gallery and the second one for taking photo. I'm using cordova camera plugin for two cases.
After choosing an image, I want to crop it before to send to server using cordova file transfer plugin. I've tried to use several plugins such as jr-crop, angular-image-crop, ngImgCrop. The problem is that plugins returns a base64 image, but I want to get the image url (not dataUrl). Any help please !
My solution (#egycode) :
$scope.image_gallery = function() {
var options = {
quality: 100,
correctOrientation: true,
sourceType: 0
};
$cordovaCamera.getPicture(options).then(function(data) {
console.log(data);
$scope.crop(data);
console.log('camera data image_gallery: ' + angular.toJson(data));
}, function(error) {
console.log('camera error image_gallery: ' + angular.toJson(error));
});
}
$scope.crop = function(url) {
$jrCrop.crop({
url: url,
width: 261,
height: 362
}).then(function(canvas) {
console.log(canvas);
var image = canvas.toDataURL();
//var image is the result, you can show it using : $scope.pictureUrl = image;
}, function() {
// User canceled or couldn't load image.
});
}

Store image to Firebase storage from cordova camera plugins on Ionic

I've red some topics on the subject (e.g: Uploading image to Firebase Storage from Cordova app) but didn't find my answer...
I'm working on a IONIC project with the implementation of the ngCordova camera plugin to take picture and get pic from the librairy.
So I got the result as a image URI and I want to upload it in Firebase storage (as file or Blob).
Here is my code :
$scope.fromCamera = function() {
$ionicPlatform.ready(function() {
var options = {
quality: 75,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.CAMERA,
allowEdit: true,
encodingType: Camera.EncodingType.JPEG,
targetWidth: 300,
targetHeight: 300,
saveToPhotoAlbum: true e
};
$cordovaCamera.getPicture(options).then(function(imageURI) {
window.resolveLocalFileSystemURL(imageURI, function (fileEntry) {
fileEntry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function () {
// This blob object can be saved to firebase
var blob = new Blob([new Uint8Array(this.result)], { type: "image/jpeg" });
// Create the storage ref
var ref = storageRef.child('images/test');
// Upload the file
uploadPhoto(blob, ref);
};
reader.readAsArrayBuffer(file);
});
}, function (error) {
console.log(error)
});
});
});
};
I read the file and convert it into a Blob before uploading it into firebase. And I got an 'Encoding error' telling me "A URI supplied to the API was malformed, or the resulting Data URL has exceeded the URL length limitations for Data URLs."
I'm running it an chrome browser with the Cordova Mocks extension.
Any help is welcome!
Thanks
uploadPhoto() is my function to upload the file on firebase storage (and save the URL in firebase database)
var storageRef = Firebase.storageRef();
var databaseRef = Firebase.databaseRef();
var uploadPhoto = function(file, ref) {
var task = ref.put(file);
// Update progress bar
task.on('state_changed', function(snapshot){
// nothing
}, function(error) {
// Handle unsuccessful uploads
}, function() {
// Handle successful uploads on complete
$scope.downloadURL = task.snapshot.downloadURL;
$scope.actualKey = databaseRef.child('posts').push().key;
databaseRef.child('posts/' + $scope.actualKey).update({
url : $scope.downloadURL,
id : $scope.actualKey,
time : firebase.database.ServerValue.TIMESTAMP,
});
}
);
}
try changing...
[new Uint8Array(this.result)]
to just this
[this.result]
alternate approach using $cordovaFile
var fileName = imageURI.replace(/^.*[\\\/]/, '');
$cordovaFile.readAsArrayBuffer(cordova.file.tempDirectory, fileName)
.then(function (success) {
// success - get blob data
var imageBlob = new Blob([success], { type: "image/jpeg" });
// Create the storage ref
var ref = storageRef.child('images/test');
// Upload the file
uploadPhoto(imageBlob, ref);
}, function (error) {
// error
});
Instead of getting the path from the URI, in the code, I assume the following...
// modify the image path when on Android
if ($ionicPlatform.is("android")) {
path = cordova.file.cacheDirectory
} else {
path = cordova.file.tempDirectory
}
feel free to parse the path to get the directory

Dropzone file not fully processed when calling processFile(File)

I'm creating a Dropzone programmatically in my Meteor application and instead of posting Files to a url I'm storing them inside my MongoDB with CollectionFS / GridFS and call processFile(File) for each one by iterating over the getQueuedFiles array, like so:
dz.getQueuedFiles().forEach(function(element) {
Images.insert(element, function(err, fileObj){
if (err){
alert("Erreur!");
} else {
var imageId = fileObj._id;
arrayOfImageIds.push(imageId);
dz.processFile(element);
}
})
All goes well until the File sizes are bigger. Then, somehow the progress bar gets stuck halfway and the processFile is never finished (and the queue not emptied). Even when I just isolate the dz.processFile(element) and comment out the DB writing the file hangs in the client.
This is my Dropzone setup:
Template.logoUpload.onRendered(function (){
Dropzone.autoDiscover = false;
dz = new Dropzone("form#dropzone", {
dictDefaultMessage : "DROP YOUR LOGO HERE",
autoProcessQueue: false,
addRemoveLinks: true,
dictRemoveFile: "Delete",
maxFiles: 2,
maxFilesize: 5,
maxThumbnailFilesize: 5,
accept: function(file, done){
done();
},
init: function() {
this.on("addedfile", function(file) {
Session.set("files", this.files.length);
if (this.getAcceptedFiles().length > 1) {
alert("max 2 files allowed");
this.removeFile(file);
}
}),
this.on("removedfile", function(file) {
Session.set("files", this.files.length);
}),
this.on("queuecomplete", function(file, response){
console.log("SUCCESFULLY UPLOADED");
console.log(arrayOfImageIds);
Session.set("imageIds", arrayOfImageIds);
})
}
});
});
Anyone have an idea how to solve this?
Have you tried increasing the file chunk size?
var imageStore = new FS.Store.GridFS("images", {
chunkSize: 1024*1024 // optional, default GridFS chunk size in bytes (can be overridden per file).
// Default: 2MB. Reasonable range: 512KB - 4MB
});
Images = new FS.Collection("images", {
stores: [imageStore]
});

Can I limit the file size for a attachinary/cloudinary upload

Using attachinary, in combination with cloudinary on Rails - is there a way to limit the size (width & height) of the uploaded image file before uploading it?
You can use an incoming transformation to limit the dimensions of the uploaded image. Larger images will be scaled down, e.g.
<%= form.attachinary_file_field :image, cloudinary: { transformation: { width: 200, height: 200, crop: :limit } } %>

Image conversion fails for bitmap images

BMP image is here: https://www.filepicker.io/api/file/fdsYv4NSaCGUefBAQmER
And the code to reproduce the failure:
var fpfile = { url: 'https://www.filepicker.io/api/file/fdsYv4NSaCGUefBAQmER',
filename: 'customers.jpg', mimetype: 'image/jpeg', isWriteable: false, size: 629454};
console.log("Converting...");
/*an element where we can display the resulting image*/
var result = document.getElementById("convert-result");
filepicker.convert(fpfile, {width: 200, height: 200},
function(new_FPFile){
console.log(new_FPFile.url);
result.src = new_FPFile.url;
}
);
Unclear what I am doing wrong here, any help would be most appreciated.
thanks
We don't currently support .bmp's for conversion, but we're in the process of adding it.