备注:本文原文首发于博客园:
https://www.cnblogs.com/hoodlum1980/p/17766287.html
【简介】
Photoshop ICO 插件是为 Photoshop 开发的功能扩展插件,使得 Photoshop 可以直接读写 ICO 格式文件。由于 Photoshop 具有强大的像素位图编辑功能,用户众多,用户基础好,这使得使用 Photoshop 制作图标变得方便,简单,快捷。而基本上降低了对多个软件协同合作的需求。也就是说,可以使用 Photoshop 就能完成绝大多数的工作,剩下一点小小的工作,例如图标文件的合并等,就属于比较简单的任务,相应的软件也比较容易开发和提供。
经过一段时间的紧张开发,在 13 年之后(2.0 版本于 2010 年发布)我终于可以发布最新版 (V3.0)的 ICO 文件格式插件了。这一次的更新我做了非常多的功能升级,最主要的新增功能特性包括:
(1)新增 X64 版本,提供这个对开发来说几乎 0 成本,但是对用户来说却很重要的一个需求。因为现在的软件和 PC 已经普遍进入 x64 时代了。
(2)新增对包含 PNG 格式图像的图标的支持,这种格式是由 windows vista 开始引入并支持的,PNG 格式图像采用 zlib 压缩,可以大大减小文件尺寸,但是一些比较古老的软件可能不支持。保存图标时,用户可以选择是否使用 PNG 格式来压缩 32 BPP 图像。
(3)新增对鼠标光标文件(cursor)的读写支持,支持设置 hotspot。
(4)在读写选项对话框上提供更强和更友好的 UI 支持,尤其是在保存图标时,用户可以实时预览到自动生成的其他尺寸和质量的图像。用户可以自由勾选想要包括在文件中的图像。尤其是对 32 BPP 为基础生成其他低质量的图标时,原来 V2.0 版提供的 alpha threshold 参数不能直观预览,使得这个参数的设置十分盲目,现在用户可以通过拖动 slider 滑竿控件,实时看到这个参数对生成图像的影响。
(5)采用质量更佳的我自己写的全像素插值的图像缩小算法。可以使得生成的小图像质量比 2.0 版本的 4 像素插值更好。
(6)生成索引图像依然采用 8 叉树算法。生成 1 BPP 的二元图像,则使用比较简单的灰度阈值方法。
(7)新增 UI 多语言支持。插件已经内置中文和英文语言资源,点击对话框上的国旗图标,可以切换界面语言。用户也可以通过语言资源模板文件,很容易为插件添加第三方语言支持。或者如果用户对内置语言有不满意之处,可以通过增加语言资源的 xml 文件,实现“覆盖”插件的内置语言资源,因为外置的语言资源文件,比插件内置的语言资源优先级更高。实现多语言,增加了很多开发精力。尽管对国人来说这一功能意义不大,但这是我非常看重的一个功能点,所以我尽最大努力将它实现了。
(8)新增对插入 BPP16 R5G6B5 格式图像的支持。V2.0 版本的插件已经支持 BPP16 图像的读取,尽管这种格式的图像在现实中应该是非常罕见,一些图像读取软件可能也不支持这种格式,但这种格式的图像还是有存在的,主要是在特殊的设备(例如比较古老的手机)或者历史时期为了降低图像文件大小的考虑。所以插件同时支持插入 BPP16 的 R5G5B5 (555)和 R5G6B5 (565)两种 BPP 16 的支持。但仅在读取或者用户选择要插入新的图像时,可以选择。保存时,插件默认不会插入 BPP16 的图像。
【下载链接】下面是新版 ICO 插件 V3.0 的下载链接:
ICO-V3.0.2.zip (博客园上的链接)
其中 x86 (32 位)版本是我主要调试的版本,使用 Photoshop CS (8.0.1)测试。x64 版本简单经过 Photoshop CS4(11.0,64 bit )的测试。
【功能简介】
(1)从 PE 文件中抽取图标
从 PE 文件中抽取图标或光标文件。打开一个含有图标,光标文件的 PE 文件,注意,如果文件是 EXE 后缀,需要先把文件后缀改为 DLL,才能打开,这点和 V2.0 时的要求一样。例如,打开 shell32.dll 时,将弹出图标资源列表。如果同时有图标和光标资源,则他们被分组显示,其中第一组是图标,第二组是光标,如下图所示:
用户可以选定一个资源,导入到 PS 中进行编辑。但是由于每次只能导入 PS 一个资源,且每个资源只能导入其中的一个图像,这使得保存时,将和 PE 文件中的资源产生差别,或者说有损的另存。为了规避这一点,所以这里也可以选择不经过 PS,而是直接把图标按照 PE 中的原样导出到硬盘文件。用户可以一次选择一个 PE 文件中的所有图标和光标,然后选择一个文件夹,点击“好”,就可以将这个 PE 文件中的所有图标和光标全部原样导出了。
在比较新的 windows 版本中,一些 DLL 的图标等不变资源被分离到了另一个以 mun 为后缀的文件(实质也是 DLL 文件,只是后缀不同)中,并放在 "C:\Windows|SystemResources" 目录下。可能是因为这些 DLL 针对不同语言可以有多个版本,但是这些图标之类的资源是不变的,所以为了避免让这些资源跟随 DLL 形成多份副本,而把这些不变的资源从原 DLL 中剥离到另一个 DLL 中进行”共享“。所以 ICO 插件新增了支持打开 ”mun“ 后缀的文件,如下图所示:
(2)选取图像
当用户选择一个图标文件,或者从 PE 中选取了一个图标导出时,如果这个资源包含多个图像,则会弹出图像选择对话框,要求用户选择要读取的图像:
在这里,用户可以选择图像,可以对图像进行放大和缩小的操作,还可以设置图标的背景,查看图标和不同背景色合成的效果。也可以显示像素网格(只有放大倍数 >= 400% 时才会显示像素网格)。插件将默认先选中图标中质量最佳的图像。如果图标只有一个图像,则这个对话框就不会显示,而是直接将唯一的图像打开到 Photoshop 文档中。打开图标之后,如果图像具有 AND MASK(非 PNG 图像),则 AND MASK 被添加到 Photoshop 的一个新建通道,之前在 V2.0 中,这个通道是和图标中的数据一致,但是会和用户对通道的自觉不符,(AND MASK 中的白色代表透明像素,黑色代表不透明像素),因此为了更符合用户直觉,在 V3.0 中,我反转了这个通道。现在 Alpha 通道对应选区,将成为代表 AND MASK 的通道的选区的子集。
用户选择预览合成效果和 Alpha 通道的信息,当鼠标在图像中移动时,对话框底部将会显示鼠标的位置和像素的 BGRA 信息。
(3)显示光标热点
当用户打开一个光标(CURSOR)文件时,这个对话框还将增加一个选项:“突出显示光标热点”,开启时,光标热点将会用一个红色十字表示其所在位置,如下图所示:
在打开光标文件时,热点将作为一个独立的通道,被添加到 Photoshop 文档中,用户能够通过通道,查看光标的 hotspot 所在位置。
(4)保存图标
保存图标时,将会弹出保存图标对话框:
这个对话框是 3.0 版本插件中最重要的功能增强。首先,对话框已经插入了其他的大小和质量的建议图像,用户可以勾选自己需要的图像。如果这些图像不满足用户需求,也可以点击“插入新图像”按钮,插入其他尺寸和质量的图像。这里最重要的就是,当从一个 32 BPP 的图像,生成其他 BPP 图像时,相当于从反锯齿图像,生成锯齿图像,这里很重要的一个参数就是对透明像素和不透明像素的区分参数:Alpha 阈值。在 32 BPP 图像中,每个像素都具有一个 alpha 信息(在 0 - 255 之间),控制和背景的 alpha 合成。0 代表完全透明,255 代表完全不透明,中间值则是半透明的合成。当降级到 BPP 小于 32 时,这些处于 0 和 255 中间的 alpha 值的像素,就必须选择要么成为透明,要么不透明,这就是 alpha threshold 这个参数的作用。插件的逻辑是:设定一个 alpha threshold:
如果 Alpha < Alpha Threshold,则这个像素将变为透明。
否则这个像素将不透明。
因此,如果 AlphaThreshold = 0,则图像将完全不透明。如果 AlphaThreshold = 256, 则图像将完全透明。
在对话框上提供了 alpha threshold 的 slider 滑竿,用户可以通过拖动滑竿,实时看到这个参数的改变,对生成图像结果的影响。它最重要的作用就是控制锯齿图像的黑边的大小,我们可以从下图看出 alpha threshold 参数对生成图像的影响:
我们可以看到当 AlphaThresh = 1 (默认值)时,生成的图像保留了最多的原图像素,也就使得阴影比较大。当增加 AlphaThresh 时,图像的阴影部分将会逐渐缩小。当拖动调节滑竿时,用户将可以实时看到生成图像的效果,因此可以更好的调节生成图像的质量。而在 v2.0 版本插件中,这个参数不能实时预览,因此只能凭感觉设置,导致生成的图像效果难以控制。
(5)设置光标热点
保存光标文件时,用户可以设置光标热点:
用户可以选择要保存到的文件类型,当选中“光标”类型时,对话框将会显示“热点”设置的按钮,点击设置热点按钮,就可以通过鼠标在图像上按下来设置热点了(这个操作和在 Visual Studio 中一致),或者直接在文本框中输入对应的数值即可。但这里我没有提供突出显示热点的功能选项,因为这个并不是那么重要。
(6)主图像(源图像)
在保存时,所有图像中有一个图像,是直接来自于 Photoshop 文档的数据,这个图像就被称之为主图像,或者源图像,所有其他图像都是从这个主图像的数据为基础,而后生成出来的。所以主图像具有很重要的作用,它在 listview 列表中,尺寸后面被加上一个感叹号,备注中也特别标明了“源自 PS 文档”,来表示这是主图像。主图像的主要作用是,对主图像的 alpha threshold 和 hotspot 的设置,将会自动传播到其他“子图像”中。因此,当选中主图像时,alpha threshold 和 hotspot 对应的控件都会用粗体字体显示,这表示这时的设置将会自动传播给其他所有图像。当选中非主图像时,这些设置将只会对当前选中的这一个图像有效,其他图像不会受到影响。
(7)设置透明色
对没有透明信息的图像,保存时,将显示设置透明色的按钮。这里对 V2.0 版本有所不同的是,我对这里的透明设置做了简化,因为 V2.0 版本在这里的设置透明色的选项有些花里胡哨,但是作用并不是很大,因为这个需求本身没那么重要和常用,所以在 V3.0 版本里我对这个功能简化成只提供设置透明色的功能,用户设置一个透明色,来把图像变为部分透明,因为在开发中有一些资源是使用透明色贴图的,所以这里可以比较方便的将其转化为图标。
(8)设置图像编码
对每个 32 BPP 的图像,用户可以自主选择是否使用 PNG 编码,这里建议是对超过 48 像素尺寸的图像,使用 PNG 编码,以使得图像尺寸较小。但是有些图像软件可能不支持 PNG 编码的图像,所以这里需要用户自行考虑。要修改图像编码设置,只需要双击对应图像的编码列,将会弹出一个 combobox,用户可以切换编码,如果没有选择 PNG 编码,则插件使用非压缩格式的 BI_RGB (Windows 位图格式)方式进行编码。
需要注意的是,只有 32 BPP 的图像才能修改编码。非 32 BPP 的图像,只能采用 BMP 存储,这是因为如果把 BPP1 - BPP 24 的图像使用 PNG 编码,将会丢失图标 AND MASK 中携带的透明信息,因此其他 BPP 不支持采用 32 BPP。
(9)全像素插值缩小算法
ICO 3.0 采用的全像素插值缩小算法,和 ICO 2.0 采用的删除像素或四像素插值算法的结果对比,如下图所示:
这里的算法是把一个 256 x 256 的 32 BPP 图像,缩小至 48 x 48 像素的 32 BPP 小图像,这里的比对效果可能不是很明显的区分“优劣”,但可以说明一些问题。那就是 ICO 2.0 算法采用的不管是删除像素(COLOR ON COLOR),还是四像素插值的方法,都因为丢失大量中间像素的颜色信息,而产生了一种“锐化”的尖锐感,如果特定图像和特定缩放比例不巧的话,还会丢失掉重要颜色信息,而使得结果不理想。而 ICO 3.0 因为是对原图所有像素都参与插值,所以结果会显得依然比较平滑,视觉效果会更加自然,给人的主观感受会更接近原图。
【参考资料】
(1)A Simple Method for Color Quantization: Octree Quantization. (生成索引图像的八叉树算法)
(2)flag icons (by mjames@gmail.com). (国旗图标)