在p5js中获取图像的像素值

时间:2019-02-15 10:43:02

标签: javascript p5.js

我一直在研究一些应该在每个黑色像素上绘制一个点(椭圆)的代码。我是get函数的新手,并且怀疑使用它可能犯了一个错误。有谁知道为什么我的代码无法成功“点”印度地图?

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.com/world/india-map.gif" alt="The map">
  <!--<img src="https://geology.com/world/india-map.gif">-->
  <p id="area"></p> <br>
  <p id="perimeter"></p>
</body>
</html>

编辑:我将代码更改为

  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.com/world/india-map.gif" alt="The map">
<!--<img src="https://geology.com/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. -->
  

但是,我在地图上得到一个黑色矩形,没有任何点。有人知道为什么会这样吗?

2 个答案:

答案 0 :(得分:1)

由于使用的是p5js,因此应使用其必须提供的方法和功能。使用p5js时不需要像您一样获得画布。键入canvas时,p5js会提供对它的引用。

此刻,您正在使用图像标签显示图像。相反,您想将图像显示在画布上。您可以通过使用p5的preload方法来加载图像。然后,一旦加载,就可以在draw方法中引用它。

您的draw方法将不断循环运行。但是,您不需要循环,因为您只需要执行一次计算即可。因此,您可以使用p5的方法noLoop()停止循环绘制。

最后,要获取特定像素的颜色,您需要使用get(x, y)。这将为您提供红色,绿色和蓝色值的数组。所有三个值均为0的地方是黑色像素。但是,您的图像的像素并非严格为黑色。例如,如果您的r g b(红色,绿色,蓝色)颜色值为1、1、1,则您的颜色仍将看起来是黑色。因此,要检查给定的颜色是否为黑色,您需要检查所有这些值是否都小于特定数字,例如80

如果将所有这些想法都整合到代码中,则应该以如下形式结束:

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();
}

您可以找到一个有效的示例here。但是请注意,这是出于演示目的。请花一些时间来了解代码。另外,当我们使用get查看画布上每个像素的颜色时,一次运行需要很长的时间来计算。 (考虑查看每2个像素,然后将椭圆绘制得更大一点)

答案 1 :(得分:1)

对尼克·帕森(Nick Parson)的出色答案做了些微调整,但使用了pixels而不是getruns almost instantly,表明get()是罪魁祸首。

//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();
}