p5js - pixelDensity() 在视网膜屏幕上没有帮助

p5js - pixelDensity() doesn't help on retina screens

我有一些代码可以从照片集生成拼贴画,我通过平均图像本身的像素颜色来实现这一点,最终,在某种操作之后,我只用平均颜色指向 (x,y)。 唯一的问题是,当我放大 视网膜屏幕(高于特定分辨率) 时,很明显这确实是屏幕上的一堆点,而不是一张完整的图像。 我想这与 pixelDensity() 有关,但经过大量实验后,它也没有帮助。

此处附有缩放裁剪示例 -

组合像素的主循环非常基本,看起来像这样 -

for (let y = 0; y <= imgOne.height; y++) {
    for (let x = 0; x <= imgOne.width; x++) {
      // Get the colors.
      const colorOne = imgOne.get(x, y);
      const colorTwo = imgTwo.get(x, y);

      let avgRed = (red(colorOne) + red(colorTwo)  ) / 2;
      let avgGreen = (green(colorOne) + green(colorTwo)) / 2;
      let avgBlue = (blue(colorOne) + blue(colorTwo)  ) / 2;
      stroke(avgRed,avgGreen,avgBlue);
      point(x, y);
      
    }
  }

点函数专门画一个直径等于pixelDensity的小圆。当您通过 CSS 变换或使用浏览器缩放功能放大 canvas 时,您将开始看到 sub-pixel 的人工制品。有两种方法可以确保您的颜色“点”是方形的并且即使在放大时也能完全填满平面:1) 使用 set() 函数明确绘制像素,2) 使用 square()rect()函数刻意画一个正方形。 (理论上你也可以直接操作 pixels 数组,但这会复杂得多)。

这是一个演示原始问题以及不同解决方案的示例。

// only show a portion of the image.
const W = 120;
const H = 120;

let imgOne;
let imgTwo;

function preload() {
  // "Recursive raytrace of a sphere" by Tim Babb is licensed under CC BY-SA 4.0
  // https://creativecommons.org/licenses/by-sa/4.0/
  imgOne = loadImage("https://upload.wikimedia.org/wikipedia/commons/thumb/3/32/Recursive_raytrace_of_a_sphere.png/240px-Recursive_raytrace_of_a_sphere.png");
  // 
  imgTwo = loadImage("https://upload.wikimedia.org/wikipedia/commons/thumb/3/31/Rainbow-gradient-fully-saturated.svg/240px-Rainbow-gradient-fully-saturated.svg.png");
}

function setup() {
  createCanvas(W * 3, H);
  noLoop();
}

function draw() {
  background(220);
  for (let y = 0; y < H; y++) {
    for (let x = 0; x < W; x++) {
      // Get the colors.
      const colorOne = imgOne.get(x, y);
      const colorTwo = imgTwo.get(x, y);

      let avgRed = (red(colorOne) + red(colorTwo)) / 2;
      let avgGreen = (green(colorOne) + green(colorTwo)) / 2;
      let avgBlue = (blue(colorOne) + blue(colorTwo)) / 2;
      stroke(avgRed, avgGreen, avgBlue);
      point(x, y);
    }
  }
  for (let y = 0; y < H; y++) {
    for (let x = 0; x < W; x++) {
      const colorOne = imgOne.get(x, y);
      const colorTwo = imgTwo.get(x, y);

      let avgRed = (red(colorOne) + red(colorTwo)) / 2;
      let avgGreen = (green(colorOne) + green(colorTwo)) / 2;
      let avgBlue = (blue(colorOne) + blue(colorTwo)) / 2;
      set(x + W, y, color(avgRed, avgGreen, avgBlue));
    }
  }
  updatePixels();

  for (let y = 0; y < H; y++) {
    for (let x = 0; x < W; x++) {
      const colorOne = imgOne.get(x, y);
      const colorTwo = imgTwo.get(x, y);

      let avgRed = (red(colorOne) + red(colorTwo)) / 2;
      let avgGreen = (green(colorOne) + green(colorTwo)) / 2;
      let avgBlue = (blue(colorOne) + blue(colorTwo)) / 2;
      fill(avgRed, avgGreen, avgBlue);
      noStroke();
      square(x + W * 2, y, 1);
    }
  }
}

// This work is licensed under a CC BY-SA 4.0 License.
// https://creativecommons.org/licenses/by-sa/4.0/
// Author: Paul Wheeler
html,
body {
  margin: 0;
  padding: 0;
}

canvas {
  display: block;
  transform-origin: top left;
  transform: scale(4);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>

为了重现问题,您需要先使用浏览器的缩放功能,然后运行 代码。我不确定为什么当您 运行 代码然后缩放时行为会有所不同。