Richard Bao 的显示图片
Richard Bao
La vie est belle !
日志 - 2008年6月
2008/6/29 13:03:23

PS 研究:标尺

说实话,以前一直没觉得 PS 的标尺有什么复杂的,不过就是按比例显示一些刻度罢了。但这次仔细一看,才发现即使是一根小小的标尺,也包含了大量的人性化设置。在不同的比例及长度单位下,应当标哪些刻度的值、每两个标注值之间划分多少个大格、小格、刻度等等。

一开始我以为它只是简单的比例换算,但后来发现并不是这样,比如在 Pixel 单位模式下,100% 比例时,50 的倍数值会显示出来,然后每 10 个像素一个大格,每 5 个像素一个小格;而在 300% 比例时,20 的倍数值会显示出来,每 10 个像素一个大格,每 2 个像素一个小格。换到 Point 单位模式下,72dpi 100% 比例时,36 的倍数值会显示出来,然后每 12 个点一大格,每 6 个点一小格等等。

经过一段时间的观察整理,总结了绘制标尺的一般方法如下:

STEP 1: 计算每单位长度的实际显示像素数 (l)

实际显示的大小同时取决于长度单位和显示缩放比例。例如对于像素来说,100% 缩放比例下,标尺上一个像素的长度实际显示也是一个像素,而在 200% 缩放比例下,一个像素的实际显示是 2 个像素。英寸等长度单位的实际尺寸依赖图像文件的分辨率设置,对于 72dpi 的 200% 缩放比例的图像来说,屏幕上一英寸实际显示需要 144 个像素单位。而百分比则依赖于图像文件的实际尺寸,对于一个 400 x 300 像素的图像,在 50% 的缩放比例下,横向 10% 的长度占据 20 个像素,而纵向 10% 的长度占据 15 个像素。

可以总结出,对于各种单位,有:

image

其中 μ 是显示缩放比例,100% 时 μ = 1;Lpx 指的是 100% 总长度(以像素为单位);dpi 指文档的分辨率值;ppi 指环境设定中点的比例值,可以是 Postscript(72 ppi)或传统(72.27 ppi)两种中的一种。

刻度线的类型与使用

刻度线有长有短,但各级刻度的间距都遵循同样的原则,并随着长度单位的变化而变化。贯穿整个标尺高度(或宽度)且其右侧(下方)标有刻度值的称为主刻度线(下图称为“主线”)。与此相反的,是密度最高、也是长度最短的刻度线(下图称为“刻度”),它代表了标尺的最高精度。除了这两种刻度线外,还可能有各级不同长度的分刻度线,它是为了在没有数值显示的情况下,便于用户识别。主/分刻度线只是对基本刻度的视觉增强,因此必然与某条刻度重叠。

Types of ticks

可以看到,并不是每次都会使用到所有级别的刻度线。只有主线是永远显示的,其次即是刻度,然后才会是各级分度。

STEP 2: 确定最小刻度间距 (d)

对于刻度线的间距来说,最根本的一条原则即是:任意两条刻度线的间距永远只可能是一些给定的特殊值,无论是最小刻度间距、或是主线间距、或是分刻度间距,都是如此。下面列出了各种长度单位下的特殊值表:

  • px/%:125、10、20、50、100、200、500……
  • inch:1/32、1/16、1/8、1/4、1/2、125、10、20、50、100、200、500……
  • cm/mm:0.1、0.2、0.5、125、10、20、50、100、200、500……
  • pt:1、3、6、12、3672144、360、720、1440……
  • pica:1/12、1/4、1/2、1、3612、30、60、120、300、600、1200……

对于最细刻度来说,一个基本原则是:最小刻度间距在屏幕上实际占据的像素距离不小于 5px。

有了 STEP 1 的基础,我们可以算出,在给定显示比例下,各种长度间距在屏幕上实际占据的像素距离。以 px/300% 的显示比例为例,其 l = 3.0,则有:

图上长度 1 2 5 10 20 50 100 200 500 ...
显示长度 3 6 15 30 60 150 300 600 1500 ...

注意其中的 2/6 被加粗了。这就是我们要找的实际显示长度刚刚大于 5px 的值。这就是最小刻度间距。实际计算中,只需先求出:

d' = 5 / l

然后在上述对应的特殊值表中,找到与 d' 相等或比它大的下一个数值,这个值即是最小刻度间距 d

STEP 3: 确定主刻度线的间距 (D)

主刻度线也是刻度线,同样遵循 STEP 2 中所述的全部规律,除此之外,它还有一些特殊的限制:

  1. 主刻度线以 0 点为基准,向正负两个方向对称延伸(这也是整个标尺的绘图基准);
  2. 主刻度线间距只能是整数;
  3. 两条主刻度线的在屏幕上实际占据的像素距离不小于 32px。

基于这三条原则,很容易可以用与 STEP 2 类似的方式确定主刻度线的间距。只需先求出:

D' = 32 / l

然后在 STEP 2 给出的特殊值表中,找到与 D' 相等或比它大的下一个数值,这个值即是 D

STEP 4: 确定其他刻度线的间距

根据刻度线自身规律来看,其他刻度线的间距必然是最小刻度间距 d 的倍数。根据观察,各级分刻度线的划分是自上而下进行的,即先划分主刻度线,划分分刻度线,直至达到最细刻度。事实上,我们只需对 STEP 2 的长度表稍加处理即可:

图上长度 1 2 5 10 20 50 100 200 500 ...
显示长度 3 6 15 30 60 150 300 600 1500 ...

加粗的两个值分别就是在前两步中已经求出的 d D。由于两级刻度线之间必须成倍数关系,因此划去了 5 这个值(5 不是 2 的整倍数)。余下的就是需要显示的分刻度值。

前面提到分刻度线有多个级别,不同级别其显示长度也不同。根据观察总结,除了主刻度线和 3px 的细刻度线外,各分刻度线在使用时,根据间距由小至大依次为:5px、4px、8px、10px。这里先使用 5px 分度,后使用 4px 分度,可能是为了照顾大部分情况下的视觉对比。

对于上例来说,也就是应当显示间距为 10 的 5px 分刻度线。整体实际显示效果即是:

300% px ruler

最后更新: 2008/6/30 0:34:45 | Windows Live Space 网站中的链接 添加评论 此链接将在新窗口中打开 | 评论 评论 (6) | Windows Live Space 网站中的链接 原文地址 此链接将在新窗口中打开
2008/6/26 16:45:22

OpenPainter 微小调整暨 PS 的画布

不是说 Open Source 就不能那么开发,而是实在是客观限制。一方面平时可用的时间非常少,一方面工程总量大得不着边际。从培养兴趣和维持成就感的角度出发,我决定改变开发模式,一点一点做大。

这样一来,UI 组件就也得同步开发,而不光是内核。首先是显示图像文档的这个基本组件,因为其他一切操作都基于它。这一阶段,我希望实现的功能是:

  1. 显示给定的图像文件
  2. 可以更改显示百分比
  3. 可以缩放显示窗口
  4. 可以显示标尺
  5. 支持各种不同的长度单位

显示图像不复杂,因为我把复杂性留给了其他的组件,身为画布显示组件(Surface),只需要直接显示传入的图片(CanvasImage)和叠加的信息合成图片(OverlayImage)即可。唯一麻烦的,是如何处理好画布区域和边界外区域(那些灰色的部分),以及滚动条的同步。

我的做法是实时绘所有的东西,双缓冲。实时计算控件尺寸和画布尺寸的大小,判断是否需要滚动条,并计算画布在屏幕上的相对位置,设置滚动条位置等等。目前看来效果还好。

最后更新: 2008/6/26 16:45:22 | Windows Live Space 网站中的链接 添加评论 此链接将在新窗口中打开 | 评论 评论 (7) | Windows Live Space 网站中的链接 原文地址 此链接将在新窗口中打开
2008/6/9 16:39:21

小破鼠标的使命终于结束

之前差不多五年的时间,都在用那种十几块钱的仿冒小鼠标,虽然基本上一年就要坏一个,但也用着还习惯,就一如既往地用着。直到这次决定换无线鼠标了,才结束了小破鼠标的历史使命。

本来打算买 Apple Wireless Mighty Mouse 的,但是它到 Windows 下面,那些附加的功能就都没有了,因此想想还是放弃了。买了一个 Microsoft 的标准鼠,附图:

最后更新: 2008/6/9 16:39:21 | Windows Live Space 网站中的链接 添加评论 此链接将在新窗口中打开 | 评论 评论 (5) | Windows Live Space 网站中的链接 原文地址 此链接将在新窗口中打开