html2canvas javascript screenshot and upload - javascript

Would it be possible to use html2canvas (This) to take a picture of the user`s screen but also upload the image, get the upload link and send it with ajax to the webserver?
if so, how can i do this?

Yes it is certainly possible to do such a thing.
Firstly use the html2canvas api to take a picture of the user's screen:
html2canvas(document.body).then(function(canvas) {
});
Secondly use the following function to convert the returned canvas image into a base64 encoded URL (defaults to png):
canvas.toDataURL();
Specification For canvas.toDataURL
Now construct a request to send your base64 encoded url to an image uploading server (I'm using Imgur as an example).
html2canvas(document.body).then(function(canvas) {
var dataURL = canvas.toDataURL();
$.ajax({
url: 'https://api.imgur.com/3/image',
type: 'post',
headers: {
Authorization: 'yourauthcode'
},
data: {
image: dataURL
},
dataType: 'json',
success: function(response) {
if(response.success) {
// Post the imgur url to your server.
$.post("yourlinkuploadserver", response.data.link);
}
}
});
});
After the image has been uploaded you can POST the URL of the uploaded image to your web server.
Specification for $.post
Specification for $.ajax

This isn't tested, but should work
function screenshot() {
html2canvas(document.body).then(function(canvas) {
// post using your favourite xhr polyfill, e.g. jQuery's
$.post('http://urlgoeshere.com', canvas.toDataURL('image/png'));
});
}
Then decode the result from base64 on the server side and put in a file

Using the example above, don't forget to add this to the base64url, otherwise it won't work :
var dataURL = canvas.toDataURL().replace(/.*,/, '');
More info here.

Related

JQuery ajax POST with FormData doesn't send any values

There seem to be lots of posts about this, but can't find a solution amongst them and I've hit a brick wall. Help, dear Stackers!
I'm writing a bit of code that lets users choose a profile picture, crop it and then save the cropped image on the server. I'm using the Cropper.js library to handle the actual cropping and have established that's working because I can display the crop live with this code:
var imageData = cropper.getCroppedCanvas().toDataURL();
var profileimage = document.getElementById('myProfilePhoto');
profileimage.src = imageData;
Now I want to send the cropped image to the server, and the best method would appear to be create a blob and Ajax that over to a php script to handle it.
cropper.getCroppedCanvas().toBlob(function (blob) {
var formData = new FormData();
formData.append('file', blob);
formData.append('uuid', '{a unique identifier}');
$.ajax({
type: 'POST',
url: '{the php script}',
data: formData,
processData: false,
contentType: false,
success: function (response) {
console.log('Upload success: '+response);
},
error: function () {
console.log('Upload error');
}
});
});
And at this stage I'm just getting my php script to var_dump($_REQUEST) so I can see in the console what the script thinks it's getting. However, the response is just sending back the default $_REQUEST objects like PHPSESSID and no file or uuid input.
What am I doing wrong?
Thanks in advance for any pointers.
If you are sending via post in order to see the request put this code
var formData = new FormData();
formData.append('file', blob);
formData.append('uuid', '{a unique identifier}');
formData.append('_method', 'PATCH'); <---add this and you're good to go
So the answer was annoyingly simple but frustratingly hard to find.
My server had an .htaccess rewrite rule which automatically changed www. addresses to the non-www version, and obviously I'd been dumb enough to include the www. in the URL I was calling, and it seems that's enough to strip off the $_POST data in these circumstances.
So FormData() and blobs are all red herrings here - it's just a redirect that's the cause.

How to send big files using ajax?

So currently I'm working on a simple project where users gets to upload an image to server. Before I mention my problem here is how I'm doing it:
Client:
var dataURL = sendingcanvas.toDataURL("image/*");
var imagedatatosend = dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
formdata = {
'image': imagedatatosend
};
$.ajax({
url: '../receive',
type: 'POST',
data: formdata,
encode: false,
success: function(result){
alert(result);
}
});
FYI: imagedatatosend size is lower than 5MB and contains exactly the file data selected.
Basically What happens Is that users select an image using <input type="file" tag Then I'm setting that selected file drawn in a canvas to convert it to base64 and send it to server.
Java Server:
String datareceived = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
byte[] bImg = Base64.decodeBase64(datareceived.getBytes("UTF-8"));
FileOutputStream fos = new FileOutputStream("hi.jpg");
fos.write(bImg);
fos.close();
I think I might not need to explain what the code above does. But I'm facing some serious performance problem I mean It takes some huge time to write the data to hi.jpg file, even if I try System.out.println(datareceived); It takes seconds for my mouse click to respond on server console.
I don't know why is it happening, Do I need to send the image data as multipart or what?
All replies are appreciated and Thanks in Advance:)
Use XMLHttpRequest and FormData to append the file. It will be sent using multipart and chunked appropriately.
See: https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects

image data response from jquery .ajax into new ajax call?

I'm trying to chain together the ImageOptim API with the OCR.space API.
Both great API's by the way, I highly recommend them! The issue at hand though is that the OCR api does not accept images over 1 mb or 2600x2600 px in the free tier and thus many sources will need to be optimised before being sent.
Im running this jQuery ajax call to ImageOptim from a cordova wrapped html file:
var compress = function(image) {
console.log("starting compress");
$.ajax({
url: "https://im2.io/eX4mp1E4pI/2600x2600,quality=low",
method: "POST",
data: {
file: image
},
processData: false,
contentType: false,
crossDomain: true
}).done(function(res) {
window.compressedImg = res;
formData.append("file", res);
runOCR();
}).fail(function(jqXHR, textStatus) {
console.log("Request failed: " + textStatus);
});
};
Please note:
this (in my experience), will fail in the browser due to cross domain calls being blocked in the browser but not from cordova.
OCR compatible compression not added in yet (but would require a file size as well as dimension argument)
The output from this call is a raw png as a string, i.e. what you get when you open a .png file in a text editor. I've tried loads of ways to handle this but cannot understand how to use this data in the next ajax call (below), does it need to be saved to disk and then uploaded, if so - how? (because I tried writing it to localstorage but it would still be treated as a string).
The OCR.space call;
var formData = new FormData();
formData.append("language", "MYLANGUAGE");
formData.append("apikey", "MYAPIKEY");
formData.append("isOverlayRequired", false);
function runOCR2() {
jQuery.ajax({
url: 'https://api.ocr.space/parse/image',
data: formData,
dataType: 'form/multipart',
cache: false,
contentType: false,
processData: false,
method: 'POST',
success: function(ocrParsedResult) {
console.log(ocrParsedResult);
}
});
}
Please note; Vars are not set here but I keep them together in this question for clarity.
The response from this call is:
responseText: "{\"ParsedResults\":null,\"OCRExitCode\":99,\"IsErroredOnProcessing\":true,\"ErrorMessage\":\"No file uploaded or UR…"
i.e. the call works but the image parameter is not a valid image.
Any ideas on how to trea the returned string so that it is readable as an image for the next api call?
Usually when you are uploading files using formData you just pass file reference like
form.append('myfile',$("#fileInput").files[0]) and browser handles the encoding stuff behind the screens .It manually converts file to byte-stream and prepares appropriate boundary to help server distinguish where image begins and ends
but here scenario is different you don't have the file bound to any physical file control instead its created dynamically and you get a bytestream of that .To account for the above fact you need to tell browser explicitly that it's a independent raw binary stuff and should be treated as such
A Blob object represents a file-like object of immutable, raw data. Blobs represent data that isn't necessarily in a JavaScript-native format.
var blob = new Blob([res], {type : 'image/png'}); //res is the converted image ImageOptim API
var formData = new FormData();
var fileName = 'myimage.png'; //filename that server will see it as
formData.append('anything', blob, fileName);
formData.append("language", "MYLANGUAGE");
formData.append("apikey", "MYAPIKEY");
formData.append("isOverlayRequired", false);
function runOCR2() {
$.ajax({
url: "https://api.ocr.space/parse/image",
type: "POST",
cache: false,
contentType: false,
processData: false,
data: formData,
success: function(response){alert(response);}
});
}

Jquery get Request Uri too long

I have a project which is built on ASP.NET MVC. There is a database table to store user's details including image, an api to output his details and view where i consume the api by ajax call. My api is returning the base64 value of image perfectly, but a 404 error comes saying request uri too long when i try to display the image.
Relevant lines of code are
$.ajax({
url: // url of api,
type: "GET",
success: function (data) {
var preview = document.querySelector('img');
preview.src = data.Image;
}
})
Does your base64-string start with data:image/png;base64,?
Look here for complete example.

How do I send image canvas data to Transloadit?

Transloadit appears to have only a Upload Form API. I wish to send the contents of my canvas to Transloadit like so:
data = canvas.toDataURL();
// POST this data to Transloadit
$.ajax({
type: 'POST',
url: 'http://api2.transloadit.com/assemblies',
// what goes here?
}).done(function() {
console.log('Done uploading!');
});
Is this possible?
It appears that Transloadit still does not support base64 data, but with newer browsers it's possible to take base64 data from a variable, convert it to binary, and send it in a file upload.
http://support.transloadit.com/discussions/questions/8587-how-to-upload-a-canvas-image-to-transloadit

Categories