Greetings,
I have a mobile app that I have built using the JSAPI that allows the user to take a picture with their iPad and posts it to a geoprocessing upload service. This is working very well, but the image size is unnecessarily large. I have a couple of functions that reduce the image size and create a BLOB that I would like to post to the same geoprocessing upload service. I have tried many different variations of posting the file using the request module in the JSAPI with no luck.
The request I make gives me a request succeeded message, but I can see in my ArcGIS Server logs that the request is actually failing (which is also odd...). The error message says "Error performing upload operation, File size or type not supported for this service". I am using the FormData which the documentation says will work, but I am obviously missing something. Here is a snippet of the code that I am using to post the reduced size image.
var data = new FormData();
data.append('file', imageResized);
var photoRequest = esriRequest({
url: url,
form: data,
content: { f: "json" },
handleAs: "blob",
load: requestSucceeded, // callback
error: requestFailed // on error
});
I would appreciate any suggestions on what I am missing.
Thanks very much!
Regards,
Tom
Solved! Go to Solution.
Here's some code I found:
// using put-selector/put to create html node
var formNode = put("form",{"method":"post","enctype":"multipart/form-data"});
var formData = new FormData(formNode);
formData.append("file",arrayBuffer,filename);
Tom,
Where is the code that produces imageResized object?
Robert,
Thanks very much for the quick reply. Here is the code that I am using to reduce the image size:
var imageResized, imageDataUrl;
var dataURLToBlob = function(dataURL) {
var BASE64_MARKER = ';base64,';
if (dataURL.indexOf(BASE64_MARKER) == -1) {
var parts = dataURL.split(',');
var contentType = parts[0].split(':')[1];
var raw = parts[1];
return new Blob([raw], {type: contentType});
}
var parts = dataURL.split(BASE64_MARKER);
var contentType = parts[0].split(':')[1];
var raw = window.atob(parts[1]);
var rawLength = raw.length;
var uInt8Array = new Uint8Array(rawLength);
for (var i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], {type: "image/jpg"});
//return new Blob([uInt8Array], {type: contentType});
}
on(dom.byId("submitRequest"), "click", sendContent);
on(dom.byId('aPhoto'), 'change', function(evt) {
// Read in file
var file = evt.target.files[0];
// Ensure it's an image
if(file.type.match(/image.*/)) {
console.log('An image has been loaded');
// Load the image
var reader = new FileReader();
reader.onload = function (readerEvent) {
var image = new Image();
image.onload = function (imageEvent) {
// Resize the image
var canvas = document.createElement('canvas'),
max_size = 800,
width = image.width,
height = image.height;
if (width > height) {
if (width > max_size) {
height *= max_size / width;
width = max_size;
}
} else {
if (height > max_size) {
width *= max_size / height;
height = max_size;
}
}
canvas.width = width;
canvas.height = height;
canvas.getContext('2d').drawImage(image, 0, 0, width, height);
imageDataUrl = canvas.toDataURL('image/jpeg');
imageResized = dataURLToBlob(imageDataUrl);
};
image.src = readerEvent.target.result;
evt.target.files[0] = readerEvent.target.result;
};
reader.readAsDataURL(file);
}
});
Regards,
Tom
Tom,
have you checked to see if the imageResized object is what you expected before you do the data.append?
Robert,
I am able to draw the resized image back on the screen with the imageDataUrl variable, but I don't really have a way to know for sure if the BLOB that is created in the imageResized variable is valid. I would think that a BLOB is a BLOB and either way I should be able to send it to the server.
Regards,
Tom
Tom,
I first thought would be a timing issue as you sure that the object is ready when you send it to the form? Can you add a setTimeout to delay and see if that helps?
Robert,
I am using the Chrome debugger and I can definitely see that the variable is loaded before I hit the upload button. The resize takes less than a second on a 4M image.
Thanks very much!
Regards,
Tom
Assuming the file size and type are not the issue as reported by the server error log, is the request using "method":"POST" and "enctype":"multipart/form-data"? When creating a FormData object I normally pass in a html <form> node that has these properties set, but I"m not sure if esriRequest(...) does this for you. Also, when calling esriRequest(), "handleAs" specifies how the response is handled in your client code and not related to what you are sending.
John,
Do you have an example of how you pass a html <form> node in a FormData object?
Regards,
Tom
Here's some code I found:
// using put-selector/put to create html node
var formNode = put("form",{"method":"post","enctype":"multipart/form-data"});
var formData = new FormData(formNode);
formData.append("file",arrayBuffer,filename);