【发布时间】:2016-04-15 11:00:01
【问题描述】:
使用画布 API 在白色背景上绘制黑色方块很容易。
尽管如此,许多设备都有不同的 window.devicePixelRatio 值,但即使有,像素的物理大小也可能不同。
能否使用 HTML5 API 检索所需的缩放因子?
如果不是,如何使用更底层的主机操作系统 API(比如说 linux、windows、android、ios、osx ...
【问题讨论】:
使用画布 API 在白色背景上绘制黑色方块很容易。
尽管如此,许多设备都有不同的 window.devicePixelRatio 值,但即使有,像素的物理大小也可能不同。
能否使用 HTML5 API 检索所需的缩放因子?
如果不是,如何使用更底层的主机操作系统 API(比如说 linux、windows、android、ios、osx ...
【问题讨论】:
真的没有办法知道 1 厘米在屏幕上会有多大。浏览器只有一个通用的屏幕 DPI 概念,通常为 96 DPI。但是,您可能坐在 19 英寸或 32 英寸的显示器旁 - 浏览器不会知道,假设它们由相同数量的像素定义,1 厘米的大小在它们之间会有很大的不同。
您必须通过物理测量尺寸来手动校准每台显示器,然后在浏览器中将其转换为每厘米或每英寸的像素数。
我制作了这个简单的工具(见下文)来进行基本校准 - 它不会为您提供科学准确的结果,但会提供足够接近的结果。是的,您必须将物理标尺放在屏幕上来测量和调整滑块,以使线条与标尺匹配。要求用户这样做当然不太实际,这是一个缺点......(可以修改为采用已知大小的已知对象)。根据需要分隔 X/Y。
当您获得屏幕的 DPI(或 PPI)后,您可以将其用作屏幕上任何内容的比例因子,以及其他方向的倒数 (1/ppi),从屏幕到路径等。
比例因子的计算结果除以 96。
var c = document.querySelector("canvas"),
ctx = c.getContext("2d"),
rng = document.querySelector("input");
ctx.translate(0.5, 0.5);
ctx.font = "16px sans-serif";
ctx.fillStyle = "#c00";
(rng.oninput = render)();
function render() {
var v = +rng.value, sepDist = 4; // 4"
ctx.clearRect(-0.5, -0.5, c.width, c.height);
ctx.strokeRect(0, 0, v, v); // draw 1:1 pixels:ppi
ctx.fillText(v + " PPI", 10, 20);
// draw marks which should be 4 inches apart
ctx.fillRect(0, 0, 3, 140);
ctx.fillRect(96 * sepDist * (v / 96), 0, 3, 140); // assuming 96 DPI base resolution
ctx.fillText("------ Should be 4 inches apart ------", 50, 140);
ctx.fillText((v / 96).toFixed(2) + "x (96 DPI)", 10, 40);
}
<label>Adjust so square below equals 1x1 inch:
<input type=range value=96 min=72 max=150></label>
<canvas width=630 height=300></canvas>
【讨论】:
window.devicePixelRatio 会给你这个价值吗?见developer.mozilla.org/en-US/docs/Web/API/Window/…。我从 devicePixelRatio 得到 1.25 的值(这意味着 120 PPI),但是当我使用上面的 sn-p 精确匹配 4 英寸时,我得到的值为 1.20(115 PPI)。那里一定有其他因素......
var ppi = (96 * window.devicePixelRatio) / 100, dpi = Math.round(96 * ppi), distanceInInches = 4; 然后要获得画布上以英寸为单位的实际距离,将distanceInInches 乘以dpi 为以上计算。