admin管理员组

文章数量:1401849

I have been working on some code that is supposed to draw a dot(ellipse) on each pixel that is black. I am new to the get function, and suspect that I might have made a mistake using it. Does anyone know why my code cannot successfully "dot" the map of India?

function setup() {
  createCanvas(400, 400);
}
                  
window.onload = function() {
  var c = document.getElementById("myCanvas");
  var ctx = c.getContext("2d");
  var img = document.getElementById("map");
  ctx.drawImage(img, 10, 10, 150000, 1800000);
}

function draw() {
  for (var x = 0; x < 100; x++){
    for (var y = 0; y < 100; y++){
      if(black(get(x,y))==255){
        ellipse(x , y, 10, 100); 
      }
    }
  }
}
    
<style>

  p {
    position:absolute;
    z-index:3;
  }

  img {
    position:absolute;
    z-index: -1;
  }
</style>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <!-- PLEASE NO CHANGES BELOW THIS LINE (UNTIL I SAY SO) -->
  <script language="javascript" type="text/javascript" src="libraries/p5.min.js"></script>
  <script language="javascript" type="text/javascript" src="p5js-temp-sadfsfdsad8981306098870070843.js"></script>
  <!-- OK, YOU CAN MAKE CHANGES BELOW THIS LINE AGAIN -->

  <!-- This line removes any default padding and style.
       You might only need one of these values set. -->
  <style> body { padding: 0; margin: 0; } </style>
</head>

<body>
  <img id="map" width="220" height="277" src=".gif" alt="The map">
  <!--<img src=".gif">-->
  <p id="area"></p> <br>
  <p id="perimeter"></p>
</body>
</html>

I have been working on some code that is supposed to draw a dot(ellipse) on each pixel that is black. I am new to the get function, and suspect that I might have made a mistake using it. Does anyone know why my code cannot successfully "dot" the map of India?

function setup() {
  createCanvas(400, 400);
}
                  
window.onload = function() {
  var c = document.getElementById("myCanvas");
  var ctx = c.getContext("2d");
  var img = document.getElementById("map");
  ctx.drawImage(img, 10, 10, 150000, 1800000);
}

function draw() {
  for (var x = 0; x < 100; x++){
    for (var y = 0; y < 100; y++){
      if(black(get(x,y))==255){
        ellipse(x , y, 10, 100); 
      }
    }
  }
}
    
<style>

  p {
    position:absolute;
    z-index:3;
  }

  img {
    position:absolute;
    z-index: -1;
  }
</style>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <!-- PLEASE NO CHANGES BELOW THIS LINE (UNTIL I SAY SO) -->
  <script language="javascript" type="text/javascript" src="libraries/p5.min.js"></script>
  <script language="javascript" type="text/javascript" src="p5js-temp-sadfsfdsad8981306098870070843.js"></script>
  <!-- OK, YOU CAN MAKE CHANGES BELOW THIS LINE AGAIN -->

  <!-- This line removes any default padding and style.
       You might only need one of these values set. -->
  <style> body { padding: 0; margin: 0; } </style>
</head>

<body>
  <img id="map" width="220" height="277" src="https://geology./world/india-map.gif" alt="The map">
  <!--<img src="https://geology./world/india-map.gif">-->
  <p id="area"></p> <br>
  <p id="perimeter"></p>
</body>
</html>

Edit: I changed the code to

  window.onload = function() {
  var c = canvas;
  var ctx = c.getContext("2d");
  var img = document.getElementById("map");
  ctx.drawImage(img, 10, 10, 150000, 1800000);
}

                  

function draw() {


for (var x = 0; x < 100; x++){
  for (var y = 0; y < 100; y++){
  if(black(get(x,y))==255){
   ellipse(x , y, 10, 100);
  
}
}
}
  

    }
    
<style> body { padding: 0; margin: 0; } </style>
</head>

<body>
<img id="map" width="220" height="277" src="https://geology./world/india-map.gif" alt="The map">
<!--<img src="https://geology./world/india-map.gif">-->
<p id="area"></p> <br>
<p id="perimeter"></p>
</body>
</html>
<style>

p{
position:absolute;
z-index:3;

}
img{
 position:absolute;
 z-index: -1;
  
}
</style>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">


  <script language="javascript" type="text/javascript" src="libraries/p5.min.js"></script>
  <script language="javascript" type="text/javascript" src="p5js-temp-sadfsfdsad1466343293693433275.js"></script>


  <!-- This line removes any default padding and style.
       You might only need one of these values set. -->
  

However, I get a black rectangle on the map and no dots. Does anyone know why this is happening?

Share Improve this question edited Feb 15, 2019 at 11:19 Bob Timmon asked Feb 15, 2019 at 10:43 Bob TimmonBob Timmon 1012 silver badges6 bronze badges 6
  • you dont have an element with id "myCanvas", so document.getElementById("myCanvas"); returns null – Krzysztof Krzeszewski Commented Feb 15, 2019 at 10:51
  • 1 In p5js you don't need to get the canvas, you can reference it using canvas – Nick Parsons Commented Feb 15, 2019 at 10:53
  • This is a weird blend of p5.js and non-p5.js approaches to graphical programming. – John Coleman Commented Feb 15, 2019 at 11:26
  • I am new to javascript and p5js and used some code snippets from the internet. – Bob Timmon Commented Feb 15, 2019 at 11:32
  • 3 Also -- what is black()? That isn't a p5.js function. As far as learning p5.js goes, I highly remend Dan Shiffman's YouTube videos on the Coding Train channel – John Coleman Commented Feb 15, 2019 at 11:33
 |  Show 1 more ment

2 Answers 2

Reset to default 5

A somewhat minor tweak of Nick Parson's excellent answer, but one that uses pixels rather than get. It runs almost instantly, which shows that get() is the culprit.

//tweak of Code from Nick Parsons

let img;

function preload() {
  img = loadImage('india-map.gif');
}

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(220);
  image(img, 0, 0, width, height);
  loadPixels();
  const d = pixelDensity();

  for (let x = 0; x < width; x++) {
    for (let y = 0; y < height; y++) {
      const i = 4 * d*(y * d*width + x);
      const [r, g, b] = [pixels[i], pixels[i + 1], pixels[i + 2]]; // get colors
      if (r <= 80 && b <= 80 && g <= 80) { // if r g b all less than 80 then color will appear black
        noStroke();
        fill(255, 0, 0);
        ellipse(x, y, 1);
      }
    }
  }
  noLoop();
}

Since you're using p5js you should use the methods and functions it has to offer. There is no need to get the canvas like you are when using p5js. p5js provides a reference to it when you type canvas.

At the moment you are using an image tag to display your image. Instead, you want to display the image to the canvas. You can do this by using p5's preload method to load the image. Then, once it has been loaded, you can reference it in your draw method.

Your draw method will constantly run on a loop. However, you don't need a loop as you only need to do your putations once. Thus you can use p5's method noLoop() to stop draw from looping.

Lastly, to get the color of a particular pixel you need to use get(x, y). This will give you an array of red, green, and blue values. A black pixel is where all three of these values are 0. However, your image has pixels which are not strictly black. For example, if your r g b (red, green, blue) color values are 1, 1, 1 your color would still look black. Thus, to check if a given color is black, you need to check if all these values are less than a particular number such as 80.

If you incorporate all these ideas into your code you should end up with something like this:

let img;

function preload() {
  img = loadImage('india-map.gif');
}

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(220);
  image(img, 0, 0, width, height);
  for(let x = 0; x < width; x++) {
    for(let y = 0; y < height; y++) {
      const [r, g, b] = get(x, y); // get colors
      if(r <= 80 && b <= 80 && g <= 80) { // if r g b all less than 80 then color will appear black
        noStroke(); // remove black outline from thing we are about to draw (the ellipse)
        fill(255, 0, 0); // make the ellipse red
        ellipse(x, y, 1); // draw the ellipse at the pixle
      }
    }
  }
  noLoop();
}

You can find a working example here. But please note, this is for demonstration purposes. Please take the time to understand the code. Also, as we are looking at every pixel's color on the canvas using get this takes a LONG time to pute once ran. (consider looking at every 2nd pixel and drawing the ellipse a little larger)

本文标签: javascriptGetting pixel values of images in p5jsStack Overflow