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);}
});
}
Related
I'm getting a PDF file from an external web resource using ajax.
I want to store this PDF in the google drive using google script API from within google docs.
Sample of that ajax call:
$.ajax({
url: "<fancyurl>",
contentType: 'application/octet-stream',
responsetype: 'blob',
type: 'GET',
success: function(response) {
// or converted response.. etc..
google.script.run.withSuccessHandler(yay).withUserObject(this).createFile(response);
});
The response from the webresource is an octet-stream:
I've tried to import the original response, the response converted to blob, a uint8 blob and the base64string. All end up in errors or corrupt files.
var blob = Utilities.newBlob(data, 'application/pdf' ,'asdf.pdf');
// blob.setName('asdf.pdf');
// blob.setContentTypeFromExtension();
DriveApp.createFile(blob);
Where data is the response or converted response.
Does anybody know how to solve this or what google script expects as a valid input?
In my experience, when the binary data is retrieved using ajax, the binary data is converted to the text data. By this, I'm worried that responsetype of blob and arraybuffer might not be able to be used. I thought that this might be the reason of your issue. So, in this answer, I would like to propose using "XMLHttpRequest" instead of "ajax".
The modified script is as follows.
Modified script:
From:
$.ajax({
url: "<fancyurl>",
contentType: 'application/octet-stream',
responsetype: 'blob',
type: 'GET',
success: function(response) {
// or converted response.. etc..
google.script.run.withSuccessHandler(yay).withUserObject(this).createFile(response);
});
To:
const xhr = new XMLHttpRequest();
xhr.open('GET', "<fancyurl>", true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
google.script.run.withSuccessHandler(yay).withUserObject(this).createFile([...new Int8Array(this.response)]);
};
xhr.send();
In this modification, the binary data is converted to the array buffer and converted it to int8 array. By this, this data can be used as the byte array with Google Apps Script.
In this case, although I cannot see your whole script of Google Apps Script, you can use your Google Apps Script as follows.
function createFile(data) {
var blob = Utilities.newBlob(data, 'application/pdf', 'asdf.pdf');
DriveApp.createFile(blob);
}
I have the following jQuery, which I think should pass a sliced file to PHP:
var blob = f.slice(start, stop);
var formData = new FormData();
formData.append('fileUpload', blob, f.name);
$.ajax({
url: 'save.php',
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(msg){
alert("Success: " + msg);
},
error: function(bla, msg){
alert("Fail: " + msg);
}
});
However, I'm not sure what the PHP should look like to save the blob to a file.
The intention is for the browser to slice the file and then save the output.
Receive it as a file at your server
<?php
//var_dump($_FILES) // check if you received it or not
$blob = $_FILES('fileUpload');
file_put_contents('/path/to/new/file_name', $blob);
?>
You might want to save the file to a tmp location first, then do some checks on it before you move it to a final location (with PHPs rename() function).
Btw: why not just save the BLOB to DB? That is a legitimate way of handling files these days, that's what the BLOB MySQL data type is for after all.
I already asked this and it worked, have a look: send formData appended with blob to server
Due to contentType: false the data is available in $_FILES rather than $_POST. One way to do it, is like so:
<?php
move_uploaded_file(
$_FILES['fileUpload']['tmp_name'],
$_FILES['fileUpload']['name']
);
?>
I have array of video files. i tried to upload. in below code console gives result empty object. How to select video file and upload. is it possible??
var pictureInput=['hp.mp4'];
var myFormData = new FormData();
myFormData.append('pictureFile', pictureInput[0]);
console.log(myFormData)
$.ajax({
url: 'uploadurl',
type: 'POST',
processData: false,
contentType: false,
dataType : 'json',
data: myFormData
});
For security reasons, it is not possible to read or upload files by name from a script. The user must either explicitly select the files from a dialog, or drag-and-drop them to the page. (If it were allowed, pages would be able to read and transmit any file on your system simply by knowing the name, which is not a good thing!)
You can find out more about how to let users specify files on the web here: https://developer.mozilla.org/en/docs/Using_files_from_web_applications
Use file object instead of file name only.
Previously i made successful this with Google App Engine (Java) and Angular 1.5
Look this accepted answer too. jQuery equivalent to XMLHttpRequest's upload?
var formData = new FormData();
formData.append('pictureFile',FILE_OBJECTS[0]);
$.ajax({
url: "YOUR_URL",
type: "POST",
data: formData,
cache: false,
contentType: false,
processData: false,
xhr: function() { // Custom XMLHttpRequest
var myXhr = $.ajaxSettings.xhr();
return myXhr;
},
}).success(function(data) {
console.log("Success")
}).error(function(data) {
console.log("Error")
});
I'm trying to send compressed data to a server. To do this I'm attempting to pass it into jQuery's ajax function as a UInt8Array. I've based this on a related answer.
But it's not worked. When I look at the content through Wireshark, I see it's tried to do a .toString() on it, getting "[object Uint8Array]". There's very little other info on this around.
var dataCompressed = LZW.compressToByteArray(data);
$.ajax({
data: dataCompressed,
processData: false,
contentType: "application/octet-stream",
url: window.localStorage.getItem('servername') + '/Form/SaveData2?formId=' + results.rows.item(x).id,
headers: { 'Authorization': 'Basic ' + credentials },
type: "POST",
async: true,
success: function (data) {
}
});
You need to serialize the ArrayBuffer before jQuery tries to convert it for you. Some examples of how to do this can be seen here.
Try creating a Blob,
var blob = new Blob([dataCompressed], {type: "application/octet-stream"});
// ...
data: blob,
If jQuery is still handling this wrong, you could put this into a FormData
var fd = new FormData();
fd.append('post_field_name', blob, 'optional_file_name');
// ...
data: fd,
Doing it one of these ways is effectively "POSTing a File with AJAX"
I don't use jQuery so whilst I assume one of the above works I've not tested it. You may find that jQuery doesn't support posting data like this and have to move to a vanilla solution
I have
$.ajax({
url: 'service url',
type: 'POST',
async : true,
contentType: false,
processData: false,
cache: false,
success: function(data){
},
error: function(err){}
});
I can see the file in my Content-disposition in the chrome inspector and the response shows an encrypted value in the inspector.
However, no file is being downloaded. What is missing here?
Content-Disposition will influence what happens when you load a resource in a browser window.
It doesn't do anything when you are handling the response manually with JavaScript.
If you want to trigger a download from that point, you'd need to handle the response, generate a data: scheme URI and set location to it.
It would be simpler to submit a form to the destination URL in the first place (unless you don't need POST in which case you can just set location to it).