Processing 像素密度?啥玩意?

语言: CN / TW / HK

在后面的源码分析中,会涉及到像素密度这个概念,想着怕部分读者有困惑,先做个铺垫文。

好啦,话不多说,进入主题!

在 Processing 中,有一个像素密度的概念,对应的接口是 pixelDensity(density) ,参数 density 必须是1或者2,其他数值都是非法的。我们先看下官方文档说明,小菜用机翻了下,准确度还不错:)

此功能是 Processing 3.0 的新增功能。它使 Processing 可以使用高分辨率屏幕(如 Apple Retina 显示器和 Windows 高 DPI 显示器)上的所有像素进行渲染。此函数只能在程序中运行一次,并且必须在没有 setup() 的程序中紧跟 size() 之后使用,并在程序有 setup() 时在 setup() 中使用。pixelDensity() 应该只与硬编码数字一起使用或与 displayDensity() 结合使用。当像素密度设置为大于 1 时,它会更改所有像素操作,包括 get()、set()、blend()、copy() 和 updatePixels() 的所有工作方式。

例子

void setup() {
size(600, 400);
// pixelDensity(displayDensity());
// pixelDensity(1);
pixelDensity(2);
println(displayDensity());
println(width, height);
println(pixelWidth, pixelHeight);
}

void draw() {
loadPixels();

for (int i = 0; i < pixelWidth * pixelHeight; i++) {
pixels[i] = color(0, 0, 255);
}

for (int i = 0; i < width * height; i++) {
pixels[i] = color(255, 255, 0);
}
updatePixels();

noLoop();
}

这个例子大家来和小菜一起来理解下。

1)像素密度设置为了2,那么 size(600, 400) ,获取到的 width 为 600, height 为 400, pixelWidth 为 1200, pixelHeight 为 800。

2)如果不设置像素密度或者设置为1,那么 size(600, 400) ,获取到的 width 为 600, height 为 400, pixelWidth 为 600, pixelHeight 为 400。这一点,尤其要注意哦。因为基本平时,大家是不会主动设置像素密度的,所以 widthpixelWidth ,以及 heightpixelHeight 都是两两相等的。

3)将 pixelWidth * pixelHeight (1200 * 800 = 960000)也就是屏幕中所有的像素都填充为蓝色 color(0, 0, 255)

4)将 width * height (600 * 400 = 240000)个数的像素,也就是屏幕 1 / 4 的区域填充为黄色 color(255, 255, 0)

ppi

提到像素密度,会经常提到 ppi 这个东西,也就是 Pixel Per Inch ,每英寸像素个数,1英寸 = 2.54厘米。

屏幕密度的计算方式:

我们拿 iPhone13 举例,图片来自 apple 官网。

5.4英寸屏幕的 ppi 达到了 476 ppi,算是超级视网膜了。

下图的 1 英寸 1 个像素,4 个像素,16 个像素

在知乎上有一篇讨论,感兴趣的可以戳 《DPI、PPI、DP、PX 的详细计算方法及算法来源是什么?》 [1]

像素密度对 loadPixels 的影响

pixelDensity(2) 的情况下,通过 loadPixels 读取到的像素数据存在了 pixels 数组中。

所以,我们要牢记住,数组 pixels 的长度本质上 pixelWidth * pixelHeight 的大小,而不是 width * height 的大小,平时没有问题,是因我们大部分情况并不会设置像素密度,默认为1的情况下,他们刚好相等而已。

像素密度对保存图片的影响

void mousePressed() {
save("sketch.png");
}

pixelDensity(2); 的情况下,我们保存下图片,可以看到图片的尺寸为 pixelWidthpixelHeight 大小。

注意:warning::不设置 pixelDensity 或者设置为1,保存的图片大小为我们通过 size(600, 400) 设置的 寸大小。

所以,我们也可以通过设置高像素密度,来保存更清晰的图片。

其他

除了上面的 loadPixelsupdatePixels 等,关于对像素的相关操作的 api,都需要大家留意一个心眼,在像素密度不为1的情况下,像素坐标的计算、获取问题。

参考资料

[1]

《DPI、PPI、DP、PX 的详细计算方法及算法来源是什么?》: https://www.zhihu.com/question/21220154

小菜与老鸟后期会不定期更新一些 Processing 绘制的代码思路分析,欢迎关注不迷路。

如果有收获,能一键三连么?