I wrote a small JavaScript-based paint program using a HTML5 canvas. What I'm trying to implement now is the ability to save the drawing to a folder on a server. The filename should be something like this: "artist"+"title"+"date" (I'm using prompts to get the artist name and the title).
How can I do this? I know I have to do something like this:
var dataURL = canvas.toDataURL();
and then use Ajax to call a PHP script. For example:
$.ajax({
type: "POST",
url: "saveImg.php",
data: {
imgBase64: dataURL
}
}).done(function(o) {
console.log('saved');
});
But how do I get the artist name and the title to the PHP script? As far as I know the file name is defined inside the PHP script, right?
Greetings
This could be accomplished in the following way ...
ᴊᴀᴠᴀꜱᴄʀɪᴘᴛ
var dataURL = canvas.toDataURL();
$.post('saveImg.php', {
imgBase64: dataURL,
artist: 'ramy',
title: 'paint',
date: new Date().toDateString()
}, function(o) {
console.log('saved');
});
ᴘʜᴘ
<?php
$img = $_POST['imgBase64'];
$artist = $_POST['artist'];
$title = $_POST['title'];
$date = $_POST['date'];
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$fileData = base64_decode($img);
$fileName = 'images/'.$artist.'_'.$title.'_'.$date.'.png';
file_put_contents($fileName, $fileData);
Related
I'm struggling with saving my canvas image to server using JavaScript and PHP. I've tried multiple examples for both JS and PHP and it always fails. There's conflicting advice on how to send image data to PHP script (base64, blob, FormData) and I'm not sure how best to communicate back to JS. Currently, zero bytes PNG files are being saved to server and I'm not sure why. I'd like to save generated canvas as a PNG on server and execute a command in JS on success. How best to approach it?
JS:
var off_canvas = document.createElement('canvas');
off_canvas.width = 1080;
off_canvas.height= 1080;
var ctx = off_canvas.getContext("2d");
var brick = new Image();
brick.src = '../img/brick-white.jpg';
brick.onload = function(){
var pattern = ctx.createPattern(this, "repeat");
ctx.fillStyle = pattern;
ctx.fill();
};
var base64img = off_canvas.toDataURL("image/jpeg");
fetch("../php/save_image.php", {
method: "POST",
image: base64img
}) .then(response => response.text())
.then(success => console.log(success)) //execute command
.catch(error => console.log(error));
PHP:
<?php
$img = $_POST['image'];
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . "/img")) {
mkdir($_SERVER['DOCUMENT_ROOT'] . "/img", 0777, true);
}
$file = $_SERVER['DOCUMENT_ROOT'] . "/img/".time().'.png';
$success = file_put_contents($file, $data);
print $success ? $file.' saved.' : 'Unable to save the file.';
?>
After some fiddling with multiple options on both JS and PHP, this is what finally worked:
JS
var off_canvas = document.createElement('canvas');
off_canvas.width = 1080;
off_canvas.height = 1080;
var off_ctx = off_canvas.getContext("2d");
off_ctx.beginPath();
off_ctx.rect(20, 20, 150, 800);
off_ctx.fillStyle = "red";
off_ctx.fill();
var brick = new Image();
brick.src = "img/brick-white.jpg";
brick.onload = function(){
var pattern = off_ctx.createPattern(brick, "repeat");
off_ctx.fillStyle = pattern;
off_ctx.fillRect(500, 0, 1000, 1000);
// needs delay to fully render to canvas
var timer = window.setTimeout(save_canvas(off_canvas), 500);
};
function save_canvas(c) {
var b64Image = c.toDataURL("image/png");
fetch("../php/save_image_b64.php", {
method: "POST",
mode: "no-cors",
headers: {"Content-Type": "application/x-www-form-urlencoded"},
body: b64Image
}) .then(response => response.text())
.then(success => console.log(success))
.catch(error => console.log(error));
}
PHP
<?php
$img = file_get_contents("php://input"); // $_POST didn't work
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . "/img")) {
mkdir($_SERVER['DOCUMENT_ROOT'] . "/img", 0777, true);
}
$file = $_SERVER['DOCUMENT_ROOT'] . "/img/".time().'.png';
$success = file_put_contents($file, $data);
print $success ? $file.' saved.' : 'Unable to save the file.';
?>
in your js page add console.log(base64img);
in your browser console, copy object. i use firefox, if you use something else, then from there copy console message.
the message will be data:image/jpeg;base64,/9j/4AAQSk......
in your php page;
$img = "data:image/jpeg;base64,/9j/4AAQSk.....";
echo "<img src='$data' />"; exit;
now you will know the image is coming or not.
if image is not showing you are not implementing the fetch method correctly
if image is showing, see if you are able to create dir/file. that is, apache has permission to create dir/file. if you are able
I'm converting svg using html2canvas to save on server side as png product preview before checkout with base64. The svg works fine. It's for a customized item checkout. The problem is after customization and checkout is clicked, the svg image does not save to preview on checkout page before checking out. Reason is i don't what to write to for the php to save it. I need help in writing the php code for "savetoserver.php" to save to server
function imagetopng(){
function showCheckout() {
$("#checkoutcontainer").show();
$(".productoverview").show();
$("#popup").show();
}
setTimeout(showCheckout, 500);
html2canvas($(".stole"), {
allowTaint: true,
letterRendering: true,
onrendered: function(canvas) {
$('.stole-png').prepend(canvas);
var dataURL = canvas.toDataURL('image/png', 1.0);
$.ajax({
type: "POST",
url: "savetoserver.php",
data: {
imgBase64: dataURL
}
})
.done(function(o) {
var fileurl = o;
var websiteurl = "http://woven.indexsta.com/";
var formatted = websiteurl + fileurl;
//var formatted = "stole-designs/" + fileurl
$('#stole-url').attr('value', formatted);
$('#stolepreview').attr('src', fileurl);
// If you want the file to be visible in the browser
// - please modify the callback in javascript. All you
// need is to return the url to the file, you just saved
// and than put the image in your browser.
});
}
});
$('.stole-png').empty();
};
$('#closecheckout').on('click touch',function(){
$("#checkoutcontainer").css('display','none');
$("#popup").css('display','none');
});
I figured it out. Incase anyone faces same challenge, here's the script i wrote to solve it.
<?php
// requires php5+
// create directory
if (!file_exists('images/')) {
mkdir('images/', 0777, true);
}
define('UPLOAD_DIR', 'images/');
$img = $_POST['imgBase64'];
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = UPLOAD_DIR . uniqid() . '.png';
$success = file_put_contents($file, $data);
print $success ? $file : 'Unable to save the file.';
?>
I have an image loaded to the browser in a HTML canvas wrapper.
<canvas id="image1" class="" width="213" height="213" style="width: 213px; height: 213px;"></canvas>
When I try to save this to the server via AJAX, it works fine but when the file is a JPEG, it doesn't redirect from the AJAX.
Here's my ajax
var imageName = $('#image_name').val();
var canvas = document.getElementById('image1');
var dataURL = canvas.toDataURL();
$.ajax({
type: "POST",
url: "script.php",
data: {
imgBase64: dataURL
}
}).done(function(data) {
alert(data);
window.location.replace("http://****.co.uk/dither/step3.php?id="+data)
});
Here's my php
<?php
define('UPLOAD_DIR', 'images/');
$img = $_POST['imgBase64'];
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = UPLOAD_DIR . uniqid() . '.png';
$success = file_put_contents($file, $data);
echo $file;
?>
If the image is a png file, then the redirect works, but if it's a JPEG it just returns back to the same page.
If I alert the 'dataURL' before the ajax call it returns a array with the first part as 'data:image/png;base64' no matter what type of file extension.
I don't know enough about the base64 stuff to figure this out.
as javascript is asynchronous the ajax was firing before the file upload had completed an thats why it was failing.
Use this sample of code to create create image from string, this will fix the issue
imagecreatefromstring($n) then imagejpeg($r,$y) or imagepng($r,$y);
and
imagedestroy($r);
I have a page with a canvas. I'm using signaturPad to capture a signature. I now need to send this signature to the php page to process and save
var saveButton = document.getElementById('save');
var cancelButton = document.getElementById('clear');
saveButton.addEventListener('click', function (event) {
var canvas = document.getElementById('signature-pad');
var dataURL = canvas.toDataURL();
console.log(dataURL);
$.ajax({
type: "POST",
url: "user_group_start_paperwork_esign2.php?group_id=1389",
data: dataURL,
//dataType: "html",
cache: false,
success: function(data){//console.log(data)
}
});
And on the PHP side
define('UPLOAD_DIR', 'images/');
$img = $_POST['data'];
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = UPLOAD_DIR . uniqid() . '.png';
$success = file_put_contents($file, $data);
print $success ? $file : 'Unable to save the file.';
But I don't seem to be sending anything. The console.log is getting the data but the $_POST['data'] seems to be empty. Thanks
Below is an element that contains inline base64 image data (abbreviated to fit here). How can JavaScript get the inline data and send it to PHP? It would be good if an intermediate canvas can be avoided, since the raw data is already available.
In the page:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEU4Xoy9WY9k6" id="photo">
The JavaScript I'm currently using to click on the element to trigger the transfer to PHP, which saves a 0 byte .png file to disk:
$("#photo").click(function() {
var xhr = new XMLHttpRequest();
xhr.open('POST', 'uploadPhoto.php', true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
var data = 'image=' + this.src;
xhr.send(data);
});
uploadPhoto.php, which receives the data and writes it to disk:
<?php
if ($_POST) {
define('UPLOAD_DIR', '/photos/');
$img = $_POST['image'];
$img = str_replace('data:image/jpeg;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = UPLOAD_DIR . uniqid() . '.png';
$success = file_put_contents($file, $data);
print $success ? $file : 'Unable to save the file.';
} else {
print 'Unable to save ' . $_POST['image'];
}
?>
What's missing?
SOLUTION UPDATE
Per #EhsanT, the png format of the raw data was not matched in the php, so this line in the php now has png where jpeg used to be:
str_replace('data:image/png;base64,', '', $img);
The only thing you are doing wrong in this particular sample code you have provided is that you have a PNG base64 image data, and in your uploadPhoto.php file you are expecting a JPG file.
So in the uploadPhoto.php file just change this line:
$img = str_replace('data:image/jpeg;base64,', '', $img);
to this:
$img = str_replace('data:image/png;base64,', '', $img);
and you are good to go