Issue : While uploading large image files i recognized that while uploading on my AWS server
having 1gb memory
uses it's full capacity, it goes upto 932 mb
usage which causes crash to the process. I was saving that image in the form of DataURI and then I read somewhere that saving it in the form of blob
can solve my problem. So i want to append that blob to formData and send to server and this is the reason i e up with this question. However if any else suggestion regarding the same problem to save image more efficient way when memory is concerned, will be appreciated.
Motive
I want to send an image to the server side as in the form of a blob
.
What I have done
I am currently having a dataURI
which I have converted into a blob
. Further, i append that blob to formData
and try to send it to server side/php using ajax.
JAVASCRIPT:
function convertURIToImageData(dataURI) {
// convert base64/URLEncoded data ponent to raw binary data held in a string
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0)
byteString = atob(dataURI.split(',')[1]);
else
byteString = unescape(dataURI.split(',')[1]);
// separate out the mime ponent
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to a typed array
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {type:mimeString});
}
//
const dataURIconverter = () =>{
let img;
var image = new Image();
image.crossOrigin = 'anonymous'; // cross domain
// create an empty canvas element
var canvas = document.createElement("canvas"),
canvasContext = canvas.getContext("2d");
image.onload = function () {
//Set canvas size is same as the picture
canvas.width = image.width;
canvas.height = image.height;
// draw image into canvas element
canvasContext.drawImage(image, 0, 0, image.width, image.height);
// get canvas contents as a data URL (returns png format by default)
var dataURL = canvas.toDataURL();
// console.log(dataURL)
let blob = convertURIToImageData(dataURL)
console.log(blob)
var formData = new FormData();
formData.append('blobImage',blob)
$.ajax({
type: 'POST',
url: 'check.php',
data: formData,
processData: false
}).done(function(data) {
console.log(data);
})
}
image.src = ".jpeg"
}
dataURIconverter()
PHP
<?php
var_dump($_POST['blobImage'])
var_dump($_POST);
//var_dump($_FILES['image']);
//$name = $_FILES['image']['tmp_name'];
//echo $name;
//echo $_FILES['image']['tmp_name'];
//$status = move_uploaded_file($name, $_FILES['image']['name']);
//echo 'successfully stored at '.$_SERVER['HTTP_HOST'];
?>
Error
I am receiving null as in console and i also checked the headers where i see formData
with the name
As you can see, $_POST
showing the blob but $_POST['blobImage']
is showing null.
Solution I require:
i am not that quick to php
so i am not sure if i am sending the blob
in the right way or receiving it.
I have provided my all possible efforts i have taken to achieve my motive.
Thanks to the munity for help.
Issue : While uploading large image files i recognized that while uploading on my AWS server
having 1gb memory
uses it's full capacity, it goes upto 932 mb
usage which causes crash to the process. I was saving that image in the form of DataURI and then I read somewhere that saving it in the form of blob
can solve my problem. So i want to append that blob to formData and send to server and this is the reason i e up with this question. However if any else suggestion regarding the same problem to save image more efficient way when memory is concerned, will be appreciated.
Motive
I want to send an image to the server side as in the form of a blob
.
What I have done
I am currently having a dataURI
which I have converted into a blob
. Further, i append that blob to formData
and try to send it to server side/php using ajax.
JAVASCRIPT:
function convertURIToImageData(dataURI) {
// convert base64/URLEncoded data ponent to raw binary data held in a string
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0)
byteString = atob(dataURI.split(',')[1]);
else
byteString = unescape(dataURI.split(',')[1]);
// separate out the mime ponent
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to a typed array
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {type:mimeString});
}
//
const dataURIconverter = () =>{
let img;
var image = new Image();
image.crossOrigin = 'anonymous'; // cross domain
// create an empty canvas element
var canvas = document.createElement("canvas"),
canvasContext = canvas.getContext("2d");
image.onload = function () {
//Set canvas size is same as the picture
canvas.width = image.width;
canvas.height = image.height;
// draw image into canvas element
canvasContext.drawImage(image, 0, 0, image.width, image.height);
// get canvas contents as a data URL (returns png format by default)
var dataURL = canvas.toDataURL();
// console.log(dataURL)
let blob = convertURIToImageData(dataURL)
console.log(blob)
var formData = new FormData();
formData.append('blobImage',blob)
$.ajax({
type: 'POST',
url: 'check.php',
data: formData,
processData: false
}).done(function(data) {
console.log(data);
})
}
image.src = "https://static.pexels./photos/248797/pexels-photo-248797.jpeg"
}
dataURIconverter()
PHP
<?php
var_dump($_POST['blobImage'])
var_dump($_POST);
//var_dump($_FILES['image']);
//$name = $_FILES['image']['tmp_name'];
//echo $name;
//echo $_FILES['image']['tmp_name'];
//$status = move_uploaded_file($name, $_FILES['image']['name']);
//echo 'successfully stored at '.$_SERVER['HTTP_HOST'];
?>
Error
I am receiving null as in console and i also checked the headers where i see formData
with the name
As you can see, $_POST
showing the blob but $_POST['blobImage']
is showing null.
Solution I require:
i am not that quick to php
so i am not sure if i am sending the blob
in the right way or receiving it.
I have provided my all possible efforts i have taken to achieve my motive.
Thanks to the munity for help.
Share Improve this question edited May 9, 2018 at 14:17 Satyam Pathak asked May 7, 2018 at 8:42 Satyam PathakSatyam Pathak 6,9323 gold badges28 silver badges52 bronze badges 3- I always remend base64 data when it es to images via ajax. So maybe convert your blob into base64 string before sending via ajax. How to? stackoverflow./a/18650249/1887622 – Brain Foo Long Commented May 9, 2018 at 12:29
-
1
* I read here on stack that saving it in the form of
blob
can be efficient* Could you please provide a link to this advice? – A.L Commented May 9, 2018 at 14:11 - If i could bookmarked that, i was searching regarding the crash issue, increased all possible limits in ini file. Than i reached to conversion to blob for such problem. It seems i am wrong with the approach. If you help me out with the advise – Satyam Pathak Commented May 9, 2018 at 14:16
3 Answers
Reset to default 5 +50Add the following three properties on your jQuery Ajax call , they are required for blobs :
cache: false,
contentType: false,
processData: false
Then do not use formData in the data property of your Ajax Call , you simply need to add your created blob. Also add a small rendering callback (apart from the console.log you already use) to print the Image. Your AJAX call gets like this :
$.ajax({
type: 'POST',
url: 'check.php',
data: blob,
cache: false,
contentType: false,
processData: false
}).done(function(data) {
document.write("<img src='"+data+"'></img>");
})
Change your PHP code to the following :
<?php
$res = file_get_contents("php://input");
echo "data:image/jpg;base64,".base64_encode($res);
?>
As far as the "php://input" use is concerned. It returns all the raw data that e after the headers of your request and it does not care what type they are which is pretty handy in most cases. Whereas $_POST will only wrap the data that have been passed with the following Content-Types :
- application/x-www-form-urlencoded
- multipart/form-data
If you really want to use FormData then you can change the request to the following :
$.ajax({
type: 'POST',
url: 'check.php',
data: formData,
cache: false,
contentType: false,
processData: false
}).done(function(data) {
console.log(data);
})
And you should also change your PHP file to get the $_FILE. Sending data this way , the Content-Type of the Request will be "multipart/form-data" which will have blobs , images and generally files on the $_FILES and the rest on the $_POST so the "php://input" will not be helpful.
<?php
var_dump($_FILES);
?>
Also keep in mind that when uploading blobs this way , they will get a random name , if you are not going to be generating filenames on the Server-Side (which you probably should in most cases) and want a specific name designated by the uploader , then you can pass it along with the FormData like :
formData.append('blobImage',blob, "MyBloBName");
If you set contentType: false
in your jQuery Ajax call , you can still use the same code with formData
and then access the file on the server through $_FILES['blobImage']
The problem is that $_REQUEST, and therefore $_GET and $_POST objects have a limitation to the number of characters available to them.
post_max_size
in PHP.ini controls the maximum size of post.
Browsers and their implementations of $_GET control the limit of a $_GET request. As it appears in their URL bar. For example IE9's limit is 2000 characters so if your blob ends up as anything more than 2000 characters in the $_GET Request. The general consensus is that $_GET requests should be much less than 255 bytes. And if you approach this limit be careful because older browsers and protocols are pletely unprepared for this.