HTML5 URL to saved image displays previously created image when clicked - javascript

I have an HTML5 app that saves the canvas image to the server and then provides a link to that image that opens in a new window.
This works fine the first time I save it, but if I create and save a new image and then click on the link it displays the old image that was previously created.
Clicking on refresh will force it to display the new one, but I was wondering if there is a way to make sure it displays the correct image so that I don't have to refresh the page?
Below is what I am using to save the image.
<script>
function saveImageAs (imgOrURL) {
if (typeof imgOrURL == 'object')
imgOrURL = imgOrURL.src;
window.win = open (imgOrURL);
setTimeout('win.document.execCommand("SaveAs")', 500);
}
</script>
<script type="text/javascript">
//****************************************************************
// Save canvas content into image file. //
//****************************************************************
function saveViaAJAX()
{
document.getElementById('saveimage').style.visibility="hidden";
document.getElementById("debugFilenameConsole").innerHTML="Please wait while your image is been generated";
var testCanvas = document.getElementById('canvas');
var canvasData = testCanvas.toDataURL("image/jpg");
var postData = "canvasData="+canvasData;
var debugConsole= document.getElementById("debugConsole");
debugConsole.value=canvasData;
//alert("canvasData ="+canvasData );
var ajax = new XMLHttpRequest();
ajax.open("POST",'savecanvas.php',true);
ajax.setRequestHeader('Content-Type', 'canvas/upload');
//ajax.setRequestHeader('Content-TypeLength', postData.length);
ajax.onreadystatechange=function()
{
if (ajax.readyState == 4)
{
//alert(ajax.responseText);
// Write out the filename.
document.getElementById("debugFilenameConsole").innerHTML="Saved as <a target='_blank' href='myimage.php'> MyImage.jpg"+ajax.responseText+"</a><br>Reload this page to start a new image or click on the link above to open the file.";
}
}
ajax.send(postData);
}
</script>
And the PHP
<?php
if (isset($GLOBALS["HTTP_RAW_POST_DATA"]))
{
// Get the data
$imageData=$GLOBALS['HTTP_RAW_POST_DATA'];
// Remove the headers (data:,) part.
// A real application should use them according to needs such as to check image type
$filteredData=substr($imageData, strpos($imageData, ",")+1);
// Need to decode before saving since the data we received is already base64 encoded
$unencodedData=base64_decode($filteredData);
//echo "unencodedData".$unencodedData;
// Save file. This example uses a hard coded filename for testing,
// but a real application can specify filename in POST variable
$fp = fopen( 'MyImage.jpg', 'wb' );
fwrite( $fp, $unencodedData);
fclose( $fp );
}
header("Content-Type: image/jpg");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("content-disposition: attachment; filename=MyImage.jpg");
imagejpeg($img, null, 100);
?>

Because you are giving the image the same name and path, the browser is helpfully caching it for you.
Use a unique path to avoid this!

You can try
var random=new Date();
var random2=getTime();
var rand=random+random2;
imgOrURL = imgOrURL.src+'?rnd='+rand
or for PHP
$rand=rand();
MyImage.php?rand=<?=$rand?>
or
$image='MyImage.php?rand='.$rand.'';
For future use, to save headache. Add dates and times first because using md5 , sha1() or a rand() or JavaScript unique key can be a nightmare, example:
/// This is much cleaner
/11.1.2012/11.05/eachier93.jpg
/11.1.2012/11.05/4358390485/93.jpg
/11.1.2012/11.10/3249203489834/234234.jpg
/// then this
/files/342748234234234/234982348394/333535.jpg
/files/4535345345/234234234234/3332.jpg
/files/23423434324/023840348234/2343.jpg

Related

Store canvas image to mysql using path location

I'm trying to save my canvas image (generated by the user in the template) in my database. I've been through a lot of sources here, majority I've combined everything on it and got pretty much confused.
Steps that I'm trying to make:
Html form where provides different choices asked from the user (done)
Each time the user selects his/her choice, beside of it is the canvas that displays the image. (done)
A button that displays the summary of his choices and the canvas image generated through modal (done)
A button to Submit his order with the image in database using php and mysql No error! But it doesn't store my image
I don't need to download it, i just want it to directly store in my database once submitted
So where I'm stuck is in the STEP 4
I'll give a summary choice on my codes: (it works fine in my file, just giving you the outcome idea)
/*This retrieves my data my JS w/c is same file with my HTML: */
$('#review').click(function () {
$('#shape').html($('input[name="shape_design"]:checked').val());
$('#color').html($('input[name="color_design"]:checked').val());
//in this part, i am getting the image displayed in the canvas based on the user's choice
var canvasSource = document.getElementById('myCanvas');
var contextSource = canvasSource.getContext('2d');
var canvasShow = document.getElementById('show_canvas');
var contextShow = canvasShow.getContext('2d');
var image = contextSource.getImageData(0, 0, canvasSource.width, canvasSource.height);
contextShow.putImageData(image, 0, 0); });
});
$(function () { //this function converts the canvas to image, so it is now called as "Show Canvas" , it display well in my modal... not sure if its the right code
$("#submitBtn").bind("click", function () {
var base64 = $('#myCanvas')[0].toDataURL();
$("#show_canvas").attr("src", base64);
$("#show_canvas").show();
});
});
//After reviewing it, this part will perform to store it in the database.. which is quite I'm confused
$('#submitOrder').click(function(confirm){
swal({ //sweetalert style
title: "ORDER SENT", },
function(submit){
setTimeout(function(){
$('#showchoices').submit(); }, 500); //"showchoices" is the name of the Html form, it will proceed to ordersent.php
});
});
For my php which I'm not sure what I'm doing.
Ordersent.php
<? php
$shape_design = $_POST['shape_design'];
$color_design = $_POST['color_design'];
$upload_dir = "upload/"; //what does this do?
$myCanvas = $_POST['myCanvas']; //myCanvas is the name and id in my form
$myCanvas = str_replace('data:image/png;base64,', '', $myCanvas);
$myCanvas = str_replace(' ', '+', $myCanvas);
$data = base64_decode($myCanvas);
$file = $upload_dir."image_name.png";
$success = file_put_contents($file, $data);
$dbc = #mysql_connect('localhost' , 'root', '');
#mysql_select_db('order_tbl', $dbc);
$query1 = "INSERT INTO choices_tbl VALUES (NULL,'$shape_design','$color_design', '$myCanvas')";
if(#mysql_query($query1,$dbc))
{ Header("Location: /home.php"); }
else { print 'error!! '.mysql_error().''; }
?>
I tried following the instructions most of the tutorial, but it doesn't work on me.
I wanted to save it in my database using PATH , my my data type in my tables are
order_tbl
designID INT(6) NOT NULL ,
shape_design VARCHAR(20) ,
color_design VARCHAR(20) ,
myCanvas VARCHAR(150) ,
am I missing an attribute?
thanks for the help in advance! Thanks for bearing with me.

When button is clicked, need to download canvas and increment sql integer by 1

I have been able to get my button to download the file (html canvas), but I need it to also increment a SQL field by one.
I am not sure how much code you will need, so I will begin by giving you the parts I am trying to get to talk to each other.
PHP:
$insert = mysql_query("update UserName set logins = logins+1 where password='$password' AND username='$username'", $connection);
HTML Button:
<div>
<a id="dload" download="YourFileName.png">Download as image</a>
</div>
JAVA (On the same page as button)
function download() {
var dt = c5.toDataURL("image/png", 1.0);
this.href = dt;
};
function insert(){
var insert = <?php $insert; ?>;
};
dload.addEventListener('click', download, false);
dload.addEventListener('click', insert, false);
The PHP code lives on a file called login.php as a variable. Login.php is included on the file that contains the HTML button and Java above.
The download part works. The SQL query is correct and works when run on the database. But I am just not sure how to integrate so it both downloads and adds one to the database.
Thanks for looking.
EDIT:
I can now get it to do both, but now it only increments the SQL field once per logon (will download every time though). The user needs to logout , then log back in for it to work properly again. I need it to increment by one every time they click download.
I changed this:
function download() {
var dt = c5.toDataURL("image/png", 1.0);
this.href = dt;
};
function insert(){
var insert = <?php $insert; ?>;
};
dload.addEventListener('click', download, false);
dload.addEventListener('click', insert, false);
to this (which is what I had originally):
function download() {
var dt = c5.toDataURL("image/png", 1.0);
this.href = dt;
};
dload.addEventListener('click', download, false);
And changed my button to this:
echo <a id="dload" download="YourFileName.png" value="<?php echo $insert; ?>">Download as image</a>

Php file upload using xmlhttprequest

I am really confused in using xmlhttprequest. I want to send a file to server. Is it necessary to use formdata to send the file. I am trying to send directly using xmlhttprequest. Instead of getting a file, I am getting only a text at server side.
var Stu_Image = localStorage.getItem('StuImage');
alert(Stu_Image);
nImageRequest[i] = new XMLHttpRequest();
nImageRequest[i].open("POST", "http://10.xxx.xx.xx/server/api/upload_image.php", true);
// var ImageFile = new Image();
ImageFile = "image="+Stu_Image;
nImageRequest[i].setRequestHeader("Content-type", "application/x-www-form-urlencoded");
alert(ImageFile);
nImageRequest[i].onreadystatechange = function (oEvent)
{
if (nImageRequest[i].readyState == 4)
{
alert("4 status:"+ nImageRequest[i].status+"-------"+ nImageRequest[i].statusText);
if (nImageRequest[i].status == 200)
{
alert(nImageRequest[i].responseText);
return;
}
else
{
alert("Error:"+ nImageRequest[i].statusText);
}
}
else
{
alert("Error:"+ nImageRequest[i].readyState +"----"+nImageRequest[i].statusText);
}
};
nImageRequest[i].send(ImageFile);
This is my php file
header("Access-Control-Allow-Origin: *");
$data = $_POST['image'];
//$data = $_FILES['image']['name'];
echo "".$data;
$fileData = base64_decode($data);
echo ".....".$fileData;
$uploads_dir = "server/api/uploads/";
move_uploaded_file($fileData, $uploads_dir);
if(!file_exists($fileData) || !is_uploaded_file($fileData))
{
//echo "";
echo "No upload";
}
else
{
echo "uploaded";
}
This is how I got Stu_Image
function loadImage(Value)
{
var reader = new FileReader();
reader.readAsDataURL(document.getElementById("LoadImage").files[0]);
ImgFile = document.getElementById("LoadImage").files[0];
/
// alert(ImgFile);
localStorage.setItem('StuImage',ImgFile);
alert(ImgFile);
// alert(url);
reader.onload = function (Event)
{
document.getElementById("PreviewImage").src = Event.target.result;
};
};
Okay, so after wasting a few days, I got the answer to this question. I hope the answer helps someone if he/she gets stuck here.I am not posting the code as it is very big. I was not encoding the image before sending to server.
So the right method is
1 Store Image on Canvas.
2 Encode it using canvas.toDataURL method and send using xmlhttprequest.
3 Decode it as server side. I used php function base64_decode to do it.
4 Use imagecreatefromstring() method to convert decoded string to image and then use imagejpeg() or imagepng() method to get the image.
Hope it helps someone. Happy to post code if required by anyone.

How can I make every user on a webpage see and edit HTML canvas live?

I am trying to make an interactive map that multiple users will be able to draw on and see each others edits live. My attempts so far have not really worked so far. Essentially, in the end, I'd like to have "rooms" that multiple users can join and then write on their own maps but for now I'd like to get it just working in general.
My thought process was this: get a script that auto refreshes an image on a webpage without refresh, make the canvas have a static background of the map I want people to write on, take what they've drawn and save it to a file every x milliseconds, combine the image that is constantly being updated with one that has all other edits, make that final image a second background image of the canvas that auto refreshes.
Now, this is probably horrifically wrong. Here is the code I have so far:
HTML/JS:
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript" src="sketch.js"></script>
<title>title</title>
<style>
body{text-align:center;}
div{padding:10px;}
img{border:2px solid #fff;border-radius:7px;}
</style>
</head>
<body onload="toImage(); saveImage(); combineImages();">
</div>
<div class="tools">
Download
</div>
<canvas id="colors_sketch" width="700" height="700"></canvas>
<img id="canvasImg" src="">
<script type="text/javascript">
$(function() {
$('#colors_sketch').sketch({defaultColor: "#ff0"});
});
function toImage() {
setInterval(function() {
var canvas = document.getElementById('colors_sketch');
var context = canvas.getContext('2d');
// save canvas image as data url (png format by default)
var dataURL = canvas.toDataURL();
// set canvasImg image src to dataURL
// so it can be saved as an image
document.getElementById('canvasImg').src = dataURL;
document.getElementById('colors_sketch').style.background = 'url(images/final_img.png), url(img/p1.jpg)';
}, 100);
}
function saveImage() {
setInterval(function() {
var canvas = document.getElementById('colors_sketch');
var context = canvas.getContext('2d');
// save canvas image as data url (png format by default)
var dataURL = canvas.toDataURL();
var onmg = encodeURIComponent(dataURL);
var xhr = new XMLHttpRequest();
var body = "img=" + onmg;
xhr.open('POST', "script.php",true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.setRequestHeader("Content-Length", body.length);
xhr.setRequestHeader("Connection", "close");
xhr.send(body);
xhr.onreadystatechange = function () {
if (xhr.status == 200 && xhr.readyState == 4) {
document.getElementById("div").innerHTML = xhr.responseText;
} else {
document.getElementById("div").innerHTML = 'loading';
}
}
}, 1000);
}
function combineImages() {
setInterval(function() {
$.ajax({
url: 'combine.php',
success:function(response){
alert(response);
}
});
}, 2000);
}
</script>
</body>
</html>
script.php:
<?php
// requires php5
define('UPLOAD_DIR', 'images/');
$img = $_POST['img'];
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = UPLOAD_DIR . 'one.png';
$success = file_put_contents($file, $data);
print $success ? $file : 'Unable to save the file.';
?>
combine.php:
<?php
$image_1 = imagecreatefrompng('images/one.png');
$image_2 = imagecreatefrompng('images/final_img.png');
imagealphablending($image_1, true);
imagesavealpha($image_1, true);
imagecopy($image_1, $image_2, 0, 0, 0, 0, 100, 100);
imagepng($image_1, 'images/final_img.png');
?>
now I'm about to scrap this whole idea just because it's not doing anything that I want it to do and it just seems to be a huge mess. Is there a completely different way of going about what I'm trying to accomplish or is there a way to actually make this work?
There are many ways to build live web applications, but the best and most modern way is to use WebSocket. You can still use older methods such as long pooling and methods that rely on timeouts.
On the client you will need a minimum of four major parts.
Websocket connector (vanilla or a library like socket.io)
Up syncing (Binding to events and notifying the connector)
Down syncing (Replicating events sent by other clients from the connector)
The canvas or WebGL related logic (input/output, drawings, shapes, etc)
On the server you will need messaging system that will relay events from a client to all other subscribed clients.
This is really easy with node.js and socket.io or ratchet for PHP.
Here is a tutorial for Node.js (Node + Express + Socket.io)
Here is an example of a socket.io client written in PHP

Ajax responseText is empty

Over the last couple of days I have learnt about the canvas-element and now I want to add AJAX to save the canvas to the server. Specifically, I am letting users draw on the canvas and when they are finished they click a button and the canvas is sent and saved to the server. The code below works excellently.
Javascript:
var testCanvas = document.getElementById('imageView');
var canvasData = testCanvas.toDataURL("image/png");
var ajax = new XMLHttpRequest();
ajax.onreadystatechange=callback();
ajax.open("POST",'script.php',true);
ajax.setRequestHeader('Content-Type', 'canvas/upload');
ajax.send("canvasData"+canvasData );
function callback (){alert ('it works!');}
PHP-code:
<?php
if (isset($GLOBALS["HTTP_RAW_POST_DATA"]))
{
// Get the data
$imageData=$GLOBALS['HTTP_RAW_POST_DATA'];
$filteredData=substr($imageData, strpos($imageData, ",")+1);
$unencodedData=base64_decode($filteredData);
$fp = fopen( 'images/'.uniqid().'.png', 'wb' );
fwrite( $fp, $unencodedData);
fclose( $fp );
echo "saved";
}
else{
echo "no raw data";
}
?>
However, I would like to have the filename and location returned to the script, so that I can present the server-side image and location to the user. I have not adjusted the php-code yet, because using the following returns an empty string:
function callback () { alert (ajax.responseText);}
I have searched and the topic seems to have been addressed a couple of times without resulting in me being able to fix the above.
Where I am going wrong?
reference functions, don't call them, and wait for the readyState to return 4
var testCanvas = document.getElementById('imageView');
var canvasData = testCanvas.toDataURL("image/png");
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = callback;
ajax.open("POST",'script.php',true);
ajax.setRequestHeader('Content-Type', 'canvas/upload');
ajax.send("canvasData"+canvasData );
function callback (){
if (ajax.readyState == 4) {
alert(ajax.responseText);
}
}

Categories