日知录

学而不思则殆

让Windows版本的Emacs支持图片直接显示

默认情况下,在Windows版本的Emacs中打开一个图片文件时,图片会被当作二进制打开,我想任何人的本意都不会是以二进制的方式打开文件;而且,如果在使用org mode时想用 iimage-mode 这个minor mode来内联地显示图片也是行不通的。

于是,把这事托付于万能的Google,还真有人为这个折腾过,于是,我就把前人折腾的过程来做个总结。

测试图片类型是否被支持

Emacs有内建函数用于测试特定类型的图片是否被支持,于是,测试几种常见类型的代码1如下:

(image-type-available-p 'png)
(image-type-available-p 'jpeg)
(image-type-available-p 'gif)
(image-type-available-p 'tiff)
(image-type-available-p 'xbm)
(image-type-available-p 'xpm)

每行的最后按下 C-x C-e ,就会返回这种类型的支持与否,支持返回 t ,不支持返回 nil 。默认情况下,在执行xpm,xbm那两行的时候会返回 t ,其它返回 nil

添加支持

下面是来自Emacs的官方文档2

Emacs has built in support for XBM and PBM/PGM/PPM images. This is sufficient to see the monochrome splash screen and tool-bar icons. Since 22.2, the official precompiled binaries for Windows have bundled libXpm, which is required to display the color versions of those images.

Emacs is compiled to recognize JPEG, PNG, GIF and TIFF images also, but displaying these image types require external DLLs which are not bundled with Emacs. See Other useful ports.

按它说的,Emacs已经内置了对JPEG,PNG,GIF和TIFF的支持了,只不过缺少外部的DLL依赖而已。所以,我们找到合适的DLL依赖就可以了。

可是,这光天化日之下,我哪知道需要哪些DLL?

别急,我从这里找到了答案,看这个问题的第一个回答,说是 image-library-alist 这个变量存储有和图片支持相关的DLL信息。

于是, C-h v 来查一下个这变量,不过出来的帮助文档说它过期了,现在需要查找 dynamic-library-alist ,没关系,再 C-h v 一下,查一下这个变量,它的内容就出来了:

Value: ((xpm "libxpm.dll" "xpm4.dll" "libXpm-nox4.dll")
 (png "libpng14-14.dll" "libpng14.dll")
 (jpeg "jpeg62.dll" "libjpeg.dll" "jpeg-62.dll" "jpeg.dll")
 (tiff "libtiff3.dll" "libtiff.dll")
 (gif "giflib4.dll" "libungif4.dll" "libungif.dll")
 (svg "librsvg-2-2.dll")
 (gdk-pixbuf "libgdk_pixbuf-2.0-0.dll")
 (glib "libglib-2.0-0.dll")
 (gobject "libgobject-2.0-0.dll")
 (gnutls "libgnutls-28.dll" "libgnutls-26.dll")
 (libxml2 "libxml2-2.dll" "libxml2.dll"))

但上面还有两段话:

Emacs tries to load the library from the files in the order they appear on the list; if none is loaded, the running session of Emacs won't have access to that library.

Note that image types `pbm' and `xbm' do not need entries in this variable because they do not depend on external libraries and are always available.

意思是说虽然列了这么一大堆,但是Emacs是按顺序load的,所以只需要有一个能被load就可以了,而pbm和xbm之所以没有出现在这个列表里面,是因为它们已经不需要外部的DLL了。

所以,整理一下,总共需要这几个DLL: libpng14-14.dlljpeg62.dlllibtiff3.dlllibgiflib4.dll

再次请出万能的Google,发现这些都可以在这里下载到,这个GnuWin32是souceforge.net上一个将GNU的工具porting到Windows的项目。(我爱open source) :-)

下载好需要的setup安装程序后,一个个安装,然后将安装目录下的bin目录路径添加到系统的PATH环境变量中,不然Emacs找不到这些DLL的话,一样没法显示图片。当然,为了图省事,也可以直接将相应的DLL从bin目录中拷出来扔到Emacs的bin目录中。

小插曲

到此似乎结束了,于是,重启Emacs打开一个图片试试,什么??还是二进制内容??于是把第一节中的那几句测试代码再跑一遍,发现其它都返回 t 只有png那一行返回 nil ,而我打开的图片刚好是png的。。于是再找张jpg打开,没有问题。

可是为什么png格式的仍旧不行呢?去安装目录的bin目录里面一看,发现跟png相关的DLL只有 libpng12.dlllibpng13.dll ,并没有我们要的 libpng14-14.dll 或者 libpng14.dll ,按这版本来看,应该是GnuWin32很久没更新png的lib,导致版本过低,低于Emacs的依赖版本。

于是,只好再次请出Google,这次在GTK的网站上发现了这个lib。于是下载 libpng_1.4.3-1_win32.zip ,把其中的 libpng14-14.dll 给解压出来丢到bin目录里面,再重启Emacs,好了,现在png格式也可以正常打开了。

Footnotes:

1

这段代码来自于这里:http://blog.csdn.net/atskyline/article/details/7569621 ,但是可能是由于时间过久的缘故,这篇文章后面的内容有误。

2

这里的第3.3节

Comments

使用Disqus评论 使用多说评论
comments powered by Disqus