Saving a lot of canvas images to server - javascript

I have a script that generates about 250 images from canvas.toDataURL().
My question is how to save them all at once (one request to server) instead of posting them individually.
I need a way to pack them in single request and then send them to PHP server for unpacking.

canvas.toDataURL() gives the byte data encoded in base64, they are safe to be used as strings and passed through HTTP.
do something like:
var images = [];
while(....) {
images.push(canvas.toDataURL());
}
var imagesJson = JSON.stringify(images);
// pseudo code of jQuery ajax, you can make use of form and a hidden field
// or any other way you'd like to query the server
$.ajax({
....
send:{images:imagesJson}
....
});
with PHP (other server side languages should almost be the same):
$images = json_decode($_POST['images'], true);
foreach($images as $image) {
$image = base64_decode($image);
file_put_contents('<path to file>', $image);
}

Related

How to show only image on the url not other content even html?

I wan't to know "How to show only image on the url not other content even html?". Like see this url link of Image. This url only shows image not any other content on webpage and also see the url of website it's dynamic url not a specific image url.
So, how to achieve that?
You simply make the request to the URL of the image.
For example, if your image is called test1.png and you have it in a directory called images, you would make the URL like this:
https://your.domain/images/test1.png
If you want to hide the full path to the images and serve them through a page (so you have some control over the request for some reason), you can do something more like the following. Let's call the PHP page img.php. And the request could be like
https://your.domain/img.php/test1
<?php
$request = './default.png';
if (isset($_SERVER['PATH_INFO'])){
$request = './images'.$_SERVER['PATH_INFO'].'.png';
if (! file_exists($request)){
$request = './default.png';
}
}
// we now know we have a valid request and the file was found
header('Content-type: image/png');
header('Content-Length: '.filesize($request));
echo file_get_contents($request);
exit;
?>
With this approach you could have any number of images in the /images/ directory and serve them if they match the request.
The website in your sample maybe using the same $_SERVER['PATH_INFO'] info approach but would be dynamically creating the image using the passed variables and explode('/',$_SERVER['PATH_INFO']) along with imagecreate()
A very quick hack version would be something like the following. The request would be like this:
https://your.domain/test.php/100x50/919/222
And the very quick code, with almost no error checking could be:
<?php
function hexToColor($hx){
$rgb = array(0,0,0);
if (strlen($hx) == 3){
$rgb[0] = hexdec($hx[0].$hx[0]);
$rgb[1] = hexdec($hx[1].$hx[1]);
$rgb[2] = hexdec($hx[2].$hx[2]);
} else {
$rgb[0] = hexdec($hx[0].$hx[1]);
$rgb[1] = hexdec($hx[2].$hx[3]);
$rgb[2] = hexdec($hx[4].$hx[5]);
}
return $rgb;
}
// default values
$sizeW = 100;
$sizeH = 100;
$bg = array(0,0,0);
$fg = array(255,255,255);
if (isset($_SERVER['PATH_INFO'])){
$opts = explode('/',substr($_SERVER['PATH_INFO'],1));
$bgSet = false;
foreach($opts as $k => $v){
// check for a width x height request
if (strpos($v,'x')){
$tmp = explode('x',$v);
$sizeW = $tmp[0];
$sizeH = $tmp[1];
} elseif ($bgSet){
// must be a foreground request
$fg = hexToColor($v);
} else {
$bg = hexToColor($v);
$bgSet = true;
}
}
}
header("Content-Type: image/png");
$im = #imagecreate($sizeW,$sizeH)
or die("Cannot Initialize new GD image stream");
$background_color = imagecolorallocate($im,$bg[0],$bg[1],$bg[2]);
$text_color = imagecolorallocate($im,$fg[0],$fg[1],$fg[2]);
imagestring($im,1,5,5,$sizeW.' x '.$sizeH,$text_color);
imagepng($im);
imagedestroy($im);
exit;
?>
But I would strongly recommend a heap of error checking before using that code!
As I understand you want to dynamically update the picture.
You can see that on their main website they created a form for the entered values:
After that, on the picture URL there are all the values you need to display this image:
https://dummyimage.com/600x400/8a1a8a/232dba&text=xzcxzcnbngh
which is this image:
what you can't see is their server side, which takes the parameters 600x400/8a1a8a/232dba&text=xzcxzcnbngh, creates a picture using their server and returning it to you.
I'll suggest you to create a server side that will return a picture and text based on the given parameters.
based on your server you will need to find out how to create the picture and return it.
As you can see here, I just modified the "src" value of the and it changed the text on the photo.
which means that their server receives the request and send back the image.
If you want a simple solution you could just send back those parameters to your page scripts, and create this image element using JavaScript.
That way, your html code will be clean without even the img element tag.
create your img in JS and send put it on the html body.
Image placeholder that’s updated by scripting
HTML code:
<img id="abc" src="">
Javascript code:
var abcImage = document.getElementById('abc');
abcImage.src = 'https://dummyimage.com/600x400/000/fff';

php canvas to image on server

I want to take the image data from my canvas on the client and save it as a .png on my server.
This is the code on my client that gets the image data from the canvas and sends it to saveImage.php:
function render()
{
var imageData = ctx.canvas.toDataURL("image/png");
var postData = "imageData="+imageData;
var ajax = new XMLHttpRequest();
ajax.open("POST","saveImage.php",true);
ajax.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
ajax.onreadystatechange=function()
{
console.log(ajax.responseText);
}
ajax.send(postData);
}
And this is what saveImage.php looks like:
<?php
if(isset($_POST["imageData"]))
{
$imageEncoded = $_POST["imageData"];
$imageDataExploded = explode(',', $imageEncoded);
$imageDecoded = base64_decode($imageDataExploded[1]);
$filename = time()."image".mt_rand();
$file = fopen("./".$filename.".png","wb");
fwrite($file, $imageDecoded);
fclose($file);
echo $filename;
exit();
}
?>
The code actually works fine, my problem is just that the images that gets created are faulty in some way.
When I try to open one, windows says that it cant show me the image because it doesn't support the format? even though its a .png?
what am I doing wrong here?
You should be encoding your data with encodeURIComponent() before including it in POST data.
You should also be using a framework like jQuery to account for browser differences. I guarantee that code will not work the same in all browsers.
On the PHP, try looking into file_put_contents() for writing data. Much quicker to type!
Have you checked what is actually being sent over HTTP? $imageEncoded probably starts with data:image/png;base64,xxxxx
Strip everything up to the comma after base64:
https://stackoverflow.com/a/15153931/3766670

How to receive a binary image in javascript?

I don't know if I missed something but I can't receive an image (binary) in javascript. I can do the same in iPhone and Android(with another cose, of course), but not if I'm using javascript.
SCENARIO:
Server Side
I have a server where the image is stored.
Code: (test1.php)
$image_url = 'http://weburbanist.com/wp-content/uploads/2011/11/lorem-ipsum.jpg';
$bin = file_get_contents($image_url);
echo $bin;
Client Side (Javascript)
I ask to the server, via URL GET/POST, the image, but I can't receive it in Javascript using AJAX request. I want to store it in a .
Code:
var activeXhr = new XMLHttpRequest();
activeXhr.open('GET', 'test1.php', true);
activeXhr.onreadystatechange = function()
{
if(activeXhr.readyState == 4){
var bin_img = activeXhr.responseText;
var dataURL="data:image/jpeg;base64,"+bin_img;
$('#test_img').attr('src',dataURL);
}
};
activeXhr.send(null);
PROBLEMS:
I can't convert this data received in BASE64 or using btoa (returns empty)
QUESTION:
How I can receive an raw image in JAVASCRIPT?
As you do already use jQuery, why not using its Ajax features for requests?
This is also much shorter:
$.get('test1.php').done(function (r) {
// r is your raw image data;
});
Also would it be appropriate to set 'Content-Type' header in php:
<?php
$image_url = 'http://weburbanist.com/wp-content/uploads/2011/11/lorem-ipsum.jpg';
$bin = file_get_contents($image_url);
header('Content-Type: image/jpeg');
die($bin); // use die/exit for safer output
Did you consider serving Base64 data from php like this:
die(base64_encode( $bin ));

AJAX Upload file straight after downloading it (without storing)

I'm making a JavaScript script that is going to essentially save an old game development sandbox website before the owners scrap it (and lose all of the games). I've created a script that downloads each game via AJAX, and would like to somehow upload it straight away, also using AJAX. How do I upload the downloaded file (that's stored in responseText, presumably) to a PHP page on another domain (that has cross origin headers enabled)?
I assume there must be a way of uploading the data from the first AJAX request, without transferring the responseText to another AJAX request (used to upload the file)? I've tried transferring the data, but as expected, it causes huge lag (and can crash the browser), as the files can be quite large.
Is there a way that an AJAX request can somehow upload individual packets as soon as they're recieved?
Thanks,
Dan.
You could use Firefox' moz-chunked-text and moz-chunked-arraybuffer response types. On the JavaScript side you can do something like this:
function downloadUpload() {
var downloadUrl = "server.com/largeFile.ext";
var uploadUrl = "receiver.net/upload.php";
var dataOffset = 0;
xhrDownload = new XMLHttpRequest();
xhrDownload.open("GET", downloadUrl, true);
xhrDownload.responseType = "moz-chunked-text"; // <- only works in Firefox
xhrDownload.onprogress = uploadData;
xhrDownload.send();
function uploadData() {
var data = {
file: downloadUrl.substring(downloadUrl.lastIndexOf('/') + 1),
offset: dataOffset,
chunk: xhrDownload.responseText
};
xhrUpload = new XMLHttpRequest();
xhrUpload.open("POST", uploadUrl, true);
xhrUpload.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
xhrUpload.send(JSON.stringify(data));
dataOffset += xhrDownload.responseText.length;
};
}
On the PHP side you need something like this:
$in = fopen("php://input", "r");
$postContent = stream_get_contents($in);
fclose($in);
$o = json_decode($postContent);
file_put_contents($o->file . '-' . $o->offset . '.txt', $o->chunk);
These snippets will just give you the basic idea, you'll need to optimize the code yourself.

File upload using base64 encoded text instead of multipart/form-data - good idea?

I currently have a django formset with dynamic number of forms. Each form has a file field.
While this works, I need a way to allow multiple files to be selected at once. I can do that with input type='file' multiple='multiple' and I can read file data using FileReader. But how can I pass these files to django formset instead of form-0-file, form-1-file etc?
I can think of one way - replace FileField with TextField, and pass around the base64 encoded file as text, but I'm not sure if it's a good solution.
Just use multiple attribute and use FILES to get all of uploaded files.
base64 encoding maybe not help
Using multiple='multiple' is not related to formset or single form. It will work natively with django. So that if you plan to have single form instead of formset, just put multiple attribute and then access request.FILES to get all of uploaded files.
You should store the Images as Files,(Here are some good answers to do that),
I already tried to store images of that way but it have a lot of problems:
Every time you go to that page, it will start loading the image again, and the people don't want to load the same image every time.
It will use a lot of bandwidth.
If you are using a free web hosting service, will spend all you your bandwidth in a couple of hours, or when you store 50 images, so that mean that your site will be out the whole month, even the services that provide unlimited hosting and bandwidth, inforce a monthly bandwidth.
I recently had a problem where I had to implement a solution where a user can upload a document, stream that to the server, and without storing in on the server, post the stream to a SOAP server.
The way I implemented it, is as follows:
I wanted to upload the file via AJAX in order for me to show the progress of the upload.
This is my solution (Please note this only catered for one file at a time - but it might be a starting point.)
JavaScript:
First declare an object for the FormData - This will be used to send any additional info along with the files:
var formData = new FormData();
Secondly append all the data you would like to send to the server:
formData.append("documentDescription", $("#documentDescription textarea").val());
formData.append("afile", file.files[0]);
Now create a new instance of XMLHttpRequest:
var xhr = new XMLHttpRequest();
This is the rest of the code that got everything working:
xhr.open("POST", "UploadDocumentURL", true);
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
var percentComplete = (e.loaded / e.total) * 100;
$('.progress .bar').css('width', percentComplete + '%').attr('aria-valuenow', percentComplete);
}
}
xhr.onload = function() {
if (this.status == 200) {
var resp = JSON.parse(this.response);
if (resp.type === "error") {
notify.add(resp.type, "Error", resp.message, 3000, true);
} else {
notify.add(resp.type, "Success", resp.message, 3000);
}
}
;
};
xhr.send(formData);
PHP
$documentName = $_POST["documentDescription"];
$fileName = $_FILES['afile']['name'];
$fileType = $_FILES['afile']['type'];
$ext = pathinfo($fileName, PATHINFO_EXTENSION);
$fileName = pathinfo($fileName, PATHINFO_FILENAME);
$fileContent = file_get_contents($_FILES['afile']['tmp_name']);
You will now have the Binary data on the server.
You should be able to make this work for multiple files by looping through the file.files[0] in JavaScript.
Hope you can apply this to your problem.

Categories