Link to home
Start Free TrialLog in
Avatar of DavidInLove
DavidInLoveFlag for France

asked on

how to get the pixel data from a canvas filter it and create a 2 canvas.

Hello,


My question is how can I get the values of the pixels in a canvas stored in a 1 dimension array.

I have been able to know the values of the pixel of a photo and transform them in canvas.

It seems stupid but I cannot find on the web how to get the data of a canvas.

In the example here I load a first canvas from images=> OK (thanks to EE)

Now I want to get the data from the first canvas to filter it and create a second canvas.

Can some one help me please?



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

.icone
{
margin-left:0px;
}


.icone-1 { background-position: left top }
.icone-2 { background-position: 14.2857% top }
.icone-3 { background-position: 28.5714% top }
.icone-4 { background-position: 42.8571% top }
.icone-5 { background-position: 57.1428% top }
.icone-6 { background-position: 71.4285% top }
.icone-7 { background-position: 85.7142% top }
.icone-8 { background-position: right top }





ul
{
padding:0px;
border:3px solid blue;
display: inline-block;
}

.icone li {
  margin:auto;
  text-align:center; /* non*/	
  vertical-align:bottom;
  padding:0px;
  width: 75px;
  height: 100px;
  border-radius:16px;
  border: solid white 5px;
  color: white;
  opacity: 1;
  background-image: url("http://www.davidinlove.com/img/sprite_menu_DT.jpg");
  background-repeat: no-repeat;
  display: inline-block;
  list-style-type:none;
}

.menuli
{
display: inline-block;
margin-top: 60px;
padding: auto;
width: 99%;
text-align:center;
border-radius:5px;
bottom: 0;
background-color: rgb(24,24,24); /* Pour les anciens navigateurs */
background-color: rgba(24,24,24,0.6);
}
</style>
</head>
<body>
  <div id="id-menu" class="c-menu">
    SPRITE<br/>
    <ul class="icone">
      <a href="#" id = "IMG1" ><li class="icone-1" id = "IMG1child" ><div class="menuli">Draw the <br\>eiffel tower</div></li></a>
      <a href="#" id = "IMG2" ><li class="icone-2" id = "IMG2child" ></li></a>
      <a href="#" id = "IMG3" ><li class="icone-3" id = "IMG3child" ></li></a>
      <a href="#" id = "IMG4" ><li class="icone-4" id = "IMG4child" ></li></a>
      <a href="#" id = "IMG5" ><li class="icone-5" id = "IMG5child" ></li></a>
      <a href="#" id = "IMG6" ><li class="icone-6" id = "IMG6child" ></li></a>
      <a href="#" id = "IMG7" ><li class="icone-7" id = "IMG7child" ></li></a>
      <a href="#" id = "IMG8" ><li class="icone-8" id = "IMG8child" ></li></a>
      </ul>
    </ul>
    </div>

<hr>
CANVAS FROM PICTURE</br>
<canvas id="myCanvas_OUT0" width="75" height="100"></canvas>

</br>
FILTERING EFFECT ON CANVAS</br>
<canvas id="myCanvas_OUT21" width="75" height="100"></canvas>
	


<script>




function custompos(p, isY, cnv, img) {
  var ti, tc;
  if (isY) {
    ti = img.height;
    tc = 100; // cnv.height;
    p = p.replace('top', '0').replace('bottom', '100%'); // ti - tc
  } else {
    ti = img.width;
    tc = 75; // cnv.width;
    p = p.replace('left', '0').replace('right', '100%'); // ti - tc
  }
  if (p.substr(-1) == '%') {
    p = Number(p.substr(0, p.length - 1)) * (ti - tc) / 100;
  }
  return p;
}


$("a").click( function(e) {
  e.preventDefault();
  img_srcout0="";
  img_srcout0= $(this).children(":first").css('background-image').replace(/^url\((['"]?)(.*?)\1\).*$/i, "$2");
  var bpos = $(this).children(":first").css('background-position');
  elemout0 = document.getElementById("myCanvas_OUT0");
  if (elemout0 && elemout0.getContext) 
  {
    contextout0 = elemout0.getContext("2d");
    if (contextout0) 
    {
      imgout0=new Image();
      imgout0.onload=function(){

        // some extra code to get position, this is not completely generic!
        var bposa = bpos.split(' ');
        var bposx = custompos(bposa[0], false, elemout0, imgout0);
        var bposy = custompos(bposa[1], true, elemout0, imgout0);
        contextout0.drawImage(imgout0,-bposx,-bposy);

        //imgdout0 = contextout0.getImageData(0, 0, 303,539);
        //pixout0 = imgdout0.data;
      };
      imgout0.src=img_srcout0;
    }
  }
});



$("#myCanvas_OUT0").on("click", function(e) {  

	//GET THE DATA OF THE myCanvas_OUT0

	var canvas_out0 = $("#myCanvas_OUT0");
	var canvasout0Position = {
		x: canvas_out0.offset().left,
		y: canvas_out0.offset().top
	};


	var elemout0 = document.getElementById("myCanvas_OUT0");
	if (elemout0 && elemout0.getContext) 
		{
		var contextout0 = elemout0.getContext("2d");
		}

	//********** It seems here is the problem
	//I need to know how to get the array with the values of the pixels of the canvas
	//This codes seems OK to take the data from a photo but my website will process data of canvas
	
	var imgdout0 = contextout0.getImageData(0, 0, 150,200);
	var pixout0 = imgdout0.data;
	
	
	//Define the second canvas
	
	
	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) 
		{
		  var contextout21 = elemout21.getContext("2d");
		  

			
		}
	
	var imgdout21 = contextout21.getImageData(0, 0, 150,200);
	var pixout21 = new Array();

	
	//FILTER THE DATA
	//This I do here in a simple example 
	
		for(j=0;j<pixout0.length;j+=4)
		{ 
			pixout21[j]=pixout0[j]/2 ;		
			pixout21[j+1]=pixout0[j+1]/2 ;		
			pixout21[j+2]=pixout0[j+2]/2 ;		
			pixout21[j+3]=255;	
		}
	
	
	
	//DISPLAY DATA IN The myCanvas_OUT21
	
		contextout21.putImageData(imgdout21, 0, 0);
	
		});

</script>

</body>
</html>

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Robert Schutt
Robert Schutt
Flag of Netherlands image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of DavidInLove

ASKER

Robert,

The code doesn't work.

Here to simplify only one question:

How can I get the array data of pixel from the canvas that you draw from sprite.

Since your code enables draw this canvas you must know how to get them?


So, I suggest We come back to your code and I just ask this question
I defined a global array pixelout0

How can I put the data in it when you draw the first canvas from the sprite

In this way I can hope to take back the data from the global array in my second function to filter and draw the second canvas

I have just added

var pixelout0 = new Array();

Open in new window


in the begining


and I would like you to tell me how to store the data of the canvas you created from sprite
in

//************B/ store the data in pixelout0 array

in the code
var pixelout0 = new Array();
function custompos(p, isY, cnv, img) {
  var ti, tc;
  if (isY) {
    ti = img.height;
    tc = 100; // cnv.height;
    p = p.replace('top', '0').replace('bottom', '100%'); // ti - tc
  } else {
    ti = img.width;
    tc = 75; // cnv.width;
    p = p.replace('left', '0').replace('right', '100%'); // ti - tc
  }
  if (p.substr(-1) == '%') {
    p = Number(p.substr(0, p.length - 1)) * (ti - tc) / 100;
  }
  return p;
}


$("a").click( function(e) {
  e.preventDefault();
  img_srcout0="";
  img_srcout0= $(this).children(":first").css('background-image').replace(/^url\((['"]?)(.*?)\1\).*$/i, "$2");
  var bpos = $(this).children(":first").css('background-position');

  elemout0 = document.getElementById("myCanvas_OUT0");
  if (elemout0 && elemout0.getContext) 
  {
    contextout0 = elemout0.getContext("2d");
    if (contextout0) 
    {
      imgout0=new Image();
      imgout0.onload=function(){

        // some extra code to get position, this is not completely generic!

       
        var bposa = bpos.split(' ');
        var bposx = custompos(bposa[0], false, elemout0, imgout0);
        var bposy = custompos(bposa[1], true, elemout0, imgout0);
        contextout0.drawImage(imgout0,-bposx,-bposy);

//************B/ store the data in pixelout0 array

      };
      imgout0.src=img_srcout0;
    }
  }
});

Open in new window

The data is not taken from the sprite image directly, but from the canvas, your existing code is fine for that. Here is a screen capture to show it works, it halves every pixel color value creating a darker version of the image, for now I assumed this is what you were after?
User generated imageHave you checked each of the 4 points? using the sprite image from your other website is not an option apparently, make it local to the test page. Using new Array() also did not work for me, so instead I used the code to get .data for the 2nd canvas.

Which browser are you using? For testing, I also uploaded it here: http://schutt.nl/ee/Q_28390058/
Hi Robert,


I don't want we loose time on this.
Your code is OK with the link to your site for every browser

When I am on local with the source code you gave (I've copied from your site) it is not working for me with GOOGLE CHROME (Version 33.0.1750.154 m) and OPERA
but it is true that with IE FireFox and Safari for windows it is OK.
I wasn't using those for first tests.


I don't know why this problem appears only on local with Google chrome but not for FF?

The first step sprite to canvas is always OK
just the second fails sometimes.


Maybe it is because of loading time for the DOM?


Thanks for your answer.
David
I can confirm now that in LOCAL testing, in Chrome (I use the same, latest version, but I don't have Opera), the security error still occurs even while the image is right there in the same directory.

The url for the image is represented as "file:///X:/..." (on my system) which is not standard perhaps but is recognised ok otherwise.

I have tried changing the image url to things like file://localhost/./sprite_menu_DT.jpg etc but nothing helps...

In the end, I assume you want this on your website, so hopefully this is not a show-stopper? Maybe there is a setting specific to ignore (for your localhost) security measures like this?
"In the end, I assume you want this on your website, so hopefully this is not a show-stopper? "

Yes it is the most important, I'll take care to test that on every devices-browser  I can from my website.
Thanks really for your help!
Glad to help.

BTW, I looked around for the error and found most people advise to run from a web server even when doing local testing, so install Apache or IIS (express) and test via http://localhost/...
OK thanks I'll try tonight home.
Robert,

That is fine.
I've opened a new question related to our previous conversation.
That is to get the canvas from sprite.

But I need have a canvas from different size.

I wanted to change with CSS attributes but it doesn't work.
In the example I try to have canvas 150 / 200 with sprite image 75 / 100


Since you did this code you may be able to improve it.

How to get a canvas from sprite image with zooming


Thanks if you have an idea.

It is quite important for the site to have bigger canvas...

Happy to hear from you.


David