• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 465
  • Last Modified:

How to save a canvas in an image on the server

Hi,


Going on with canvas now I want to save my canvas that I've created on the server in an image.


Here is the code that enables me to have the data of the canvas

var canvas = document.getElementById("myCanvas_OUT0");
var context = canvas.getContext("2d");
var pixout0 = context.getImageData(0, 0, 75, 100).data;

Open in new window


Does some one know how to convert this in a png or jpeg image and save it in a directory please?

Thanks!
0
DavidInLove
Asked:
DavidInLove
  • 5
  • 4
  • 2
1 Solution
 
Ray PaseurCommented:
Please give us a bit of help with your question.  Set up the SSCCE* so that we can copy / paste your code into our code editors and save it on our servers.  Then we can run it and get the same results you get.  Once we have that foundation we can experiment with the test case and collaborate on a solution.  

Thanks, ~Ray

* Required reading for software developers!
0
 
DavidInLoveAuthor Commented:
HI here is a working code to create the canvas and get back the data.

I just now want to save it in an image on the server.

Thanks for your attention!
David

<!DOCTYPE html>
<html>
<head>
<title> EE Q_28383720 </title>
<script src="http://code.jquery.com/jquery.min.js"></script>

</head>
<body>
I want to save the canvas created in an image on the server when I click on it </br>

<canvas id="myCanvas_OUT21" width="75" height="100"></canvas>
	


<script>

var contextout0, contextout21;


	$("#myCanvas_OUT21").click ( function()
		{
		
		alert("Here I want to save the canvas created in an image on the server");
		
		
		//Here is the data of the canvas How can I convert it in an image and save it on the server?
		var canvas = document.getElementById("myCanvas_OUT21");
		var context = canvas.getContext("2d");
		var pixout21 = context.getImageData(0, 0, 75, 100).data;

		//alert(pixout21[0]);
		});


$("document").ready( function() {  


	
	
	var canvas_out21 = $("#myCanvas_OUT21");
	var canvasout21Position = {
		x: canvas_out21.offset().left,
		y: canvas_out21.offset().top
	};
	var elemout21 = document.getElementById("myCanvas_OUT21");
	if (elemout21 && elemout21.getContext) 
		{
		  contextout21 = elemout21.getContext("2d");
		  

			
		}
	
	var imgdout21 = contextout21.getImageData(0, 0, 75, 100);
	var pixout21 = imgdout21.data; //new Array();

	
	//FILTER THE DATA
	//This I do here in a simple example 
	
		for(j=0;j<75*100*4;j+=4)
		{ 
			if (j%5)
			{
			
			pixout21[j]=255 ;		
			pixout21[j+1]=255;		
			pixout21[j+2]=255 ;		
			pixout21[j+3]=255;	
			

			}
			else
			{
			pixout21[j]=100/3 ;		
			pixout21[j+1]=100[j+1]/3 ;		
			pixout21[j+2]=100[j+2]/3 ;		
			pixout21[j+3]=255;	
			
			}
		}
	
	
	
	//DISPLAY DATA IN The myCanvas_OUT21
	
		contextout21.putImageData(imgdout21, 0, 0);
	
		});
		
		


</script>

</body>
</html>

Open in new window

0
 
Ray PaseurCommented:
This will take me a while, but it's a great question and I'm fairly certain I can produce a demonstration script from the code you've provided.  The theory is this: Each pixel of the canvas is a pixel of the image.  Each pixel has 4 channels: Red, Green, Blue and Alpha (transparency).  The pixels are numbered from zero to "n" in modulo 4.  Pixel zero at the top left has 4 bytes associated with it, one for each channel. Pixel one, immediately to the right of pixel zero, has the next 4 bytes, etc.  To make an image in PHP you will have to know the canvas dimensions, width and height, so you can create an image resource of the correct dimensions.  Then it's just a matter of filling in the pixels of the image resource one at a time with the appropriate color and transparency.

In PHP the alpha channel values only go up to 127 (not 255) so that bit of data has to be interpolated.  My guess is that the RGB values are consistent across JS and PHP.
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
DavidInLoveAuthor Commented:
Hi,
Thanks for your time!

On the internet I see people speak of  base64_encode($str);  that seems to tell about image
coding but I don't know really what it is.

Wait a little I've found some code that create an image to download it from canvas.
Only I would like also to store it in a directory

I will put the PHP code tonight in this post.
You may find an easy way to store the image created on the server and not only download it.

Happy to hear from you!
David
0
 
Ray PaseurCommented:
I've gotten some of this into a "sensible" model, but not all of it.  There may be a setting in my server that is causing trouble and more research is needed to figure that out.

I can capture the data from the canvas in four-byte chunks giving R, G, B, and A values.  But when I try to send this data to my server with an AJAX request, I only get the first 5,000 elements in the $_POST array.  I may need some other form of encoding to get all 30,000 of the data elements from the canvas in this test case.

I do not believe that base64_encode() is needed here.

More to follow...
0
 
Slick812Commented:
greetings DavidInLove, this is not very difficult to do , , IF the many browsers out there would have a reasonable working javascript for the canvas.toDataURL() method, but due to different versions and browsers (this is a very recent addition to the canvas spec) it is not consistent.
Anyway there is a google code that can do this to get a base64 png file, it is called by -
<script src="http://todataurl-png-js.googlecode.com/svn/trunk/todataurl.js"></script>

below are two working Files to use this thing , first a html file, that is the canvas file -
<!doctype html><html><head><title>Canvas to PNG</title>
<style>body{background:#fda;}</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<script src="http://todataurl-png-js.googlecode.com/svn/trunk/todataurl.js"></script>
<script>/* <![CDATA[ */
function draw_square() {
   ctx.fillStyle = "#f08";
   ctx.fillRect(5, 5, 13, 13);
   var td = can.toDataURL();// h 22
   td = td.substr(22);//,iVBOR
   //alert(td.length+":length "+td);
   document.getElementById("ih").value = td;
   document.pngF.submit();
}
/* ]]> */</script></head>
<body>
<canvas id="cv1" width="25" height="25" style="width:56px;height:56px;border:2px solid black;"></canvas><button id="bt1" onclick="draw_square();">CanvasUR</button>
<form name="pngF" action="canpng.php" method="post">
<input id="ih" type="hidden" name="png" value=" " />
</form>
<script>/* <![CDATA[ */
var can = document.getElementById("cv1");
var ctx = can.getContext("2d");
ctx.fillStyle = "#cdf";
ctx.fillRect(0, 0, 25, 25);
ctx.moveTo(0,0);
ctx.lineTo(25,25);
ctx.stroke();
ctx.moveTo(0,25);
ctx.lineTo(25,0);
ctx.stroke();
/* ]]> */</script>
</body></html>

Open in new window


next is the PHP file named canpng.php , It gets the base64 and writes it to a png file , shown on the return PHP page-
<!doctype html><html><head><title>Canvas to PNG PHP</title>
<style>body{background:#afa;}</style></head>
<body><h3>Canvas to PNG PHP</h3>
<?php ini_set("display_errors",1); error_reporting(E_ALL);

$png64 = (empty($_POST['png'])) ? 0 : $_POST['png'];
if (!$png64) {
  echo '<b>ERROR, the PNG base64 was NOT SENT in post!</b><br />';
  exit();
  }

$png64 = base64_decode($png64);
file_put_contents('canpng1.png', $png64);

/* below code if you want to experiment
$size_info = getimagesizefromstring($png64);
if (!$size_info) {
  echo '<b>ERROR, the PNG Image Data is Corupt</b><br />';
  exit();
  }
echo '<p>png Image height is '.$size_info[1].', width is '.$size_info[0].'</p><hr>';

$im = imagecreatefromstring($png64);
if ($im !== false) {
  imagepng($im,'canpng1.png');
  imagedestroy($im);
  }else echo 'An error occurred in imagecreatefromstring().';
*/
?>
<img src="canpng1.png" />
</body></html>

Open in new window

These two file work on my server.
ask questions if you need more information.
0
 
DavidInLoveAuthor Commented:
Thanks Slick812,

Your solution works perfectly on my server too!

Sorry for other EE contribution but I must give all the points here to stay honest.

David
0
 
Ray PaseurCommented:
Glad you're OK with the solution.  But I found that the images looked different after the transfer to the server.  Using Chrome at latest release.
0
 
Slick812Commented:
@ray, they are suppose to look different, examine the -
<canvas id="cv1" width="25" height="25" style="width:56px;height:56px;border:2px solid black;"></canvas>

which increases the actual height and width from 25 pixels to a displayed of 56 pixels

if you look at the javascript I add a violet-red rectangle to canvas just before server send.

I use a small canvas 25x25 just so I do not have to deal with large string debug for development.

works great in my chrome. If not work, do you have a fix?
0
 
Ray PaseurCommented:
Hey, Slick812 - it's not up to me.  If the answer is good for the Author of the question, that's fine.  I was only offering an observation that the image in the canvas and the image stored on my server looked different.  Whether that's a "bug" or a "feature" is open to interpretation.  As long as the Author is happy, I'm happy.
0
 
DavidInLoveAuthor Commented:
I've included it in my website and haven't seen really buggs too.
It is true that I haven't tested all the browsers...
But It's OK for me.
Best regards
Thanks to both of you.
Dave
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 5
  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now