Solved

How to save a canvas in an image on the server

Posted on 2014-03-19
11
441 Views
Last Modified: 2014-03-24
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
Comment
Question by:DavidInLove
  • 5
  • 4
  • 2
11 Comments
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39939259
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
 

Author Comment

by:DavidInLove
ID: 39941917
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
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39942892
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
 

Author Comment

by:DavidInLove
ID: 39944787
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
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39945387
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
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 33

Accepted Solution

by:
Slick812 earned 500 total points
ID: 39945608
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
 

Author Closing Comment

by:DavidInLove
ID: 39945789
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
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39946585
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
 
LVL 33

Expert Comment

by:Slick812
ID: 39947832
@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
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39947946
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
 

Author Comment

by:DavidInLove
ID: 39949707
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

Easy Project Management (No User Manual Required)

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
SVG Logo 4 19
Login area of a page 4 19
Bootstrap css to change alignment without using padding 3 27
wordpress issue 2 21
Introduction Knockoutjs (Knockout) is a JavaScript framework (Model View ViewModel or MVVM framework).   The main ideology behind Knockout is to control from JavaScript how a page looks whilst creating an engaging user experience in the least …
How to build a simple, quick and effective accordion menu using just 15 lines of jQuery and 2 css classes
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now