动态生成 GIF 图像

作者:Jimmy Ball

万维网上最不为人知的秘密之一是如何实时或“动态”创建 GIF 图像。动态创建 GIF 图像的一些原因包括突出显示地图图像、将多个图像合并为一个(类似于 CAD 软件包中的图层功能),甚至制作虚拟明信片。

我开发程序来动态创建 GIF 图像的原因是为了制作校园地图,以突出显示重要的位置。也就是说,当任何人访问我们的校园地图网页并选择要定位的特定建筑物或地点时,我们都希望以某种方式突出显示该特定地点。

与大多数项目一样,所有细节都没有事先确定,所以我选择了一条可以节省我时间的开发路线——我决定编写一个程序来自动化这项任务。对我来说,编程比编辑 100 个或更多图像更有趣,尤其是在人们倾向于改变主意的时候。事实证明,开发时间并不长,当需要修改时,这只是一件微不足道的小事。

在本文中,我简化了我的项目,并概述了通过向现有图像添加箭头来创建新 GIF 图像的步骤。您需要熟悉 Perl 中的 CGI 编程以及 HTML。您必成为专家。

入门指南

首先,下载并安装下面列出的项目。

  1. Perl:这是我们将要使用的编程语言。对于 CGI 程序,我通常从 Perl 程序开始,然后在程序速度成为瓶颈时迁移到 C。您将需要至少 5.002 版本的 Perl。如果您尚未安装,请从 https://perldotcom.perl5.cn/perl/ 下载。在上面的 URL 中也应该有指向 Windows 95/NT 版本的 Perl 的链接。据我所知,所有 Perl 实现都是免费的。

  2. GD.pm 接口:此接口提供图形命令以进行 GIF 图像操作。它由 Lincoln Stein 开发,基于 Thomas Boutell 开发的 gd C 库 (http://www.boutell.com/gd/)。您可以从 http://www-genome.wi.mit.edu/ftp/pub/software/WWW/GD.html 免费获取 GD.pm。

  3. Web 服务器:此示例是在 Apache 1.2 web 服务器上开发的。但是,只要 web 服务器允许您用 Perl 编写 CGI 脚本,并且 Perl 已安装为 CGI 语言,它就应该可以工作。您可以从 https://apache.ac.cn/ 免费获取 Apache。还有其他免费软件和商业 web 服务器,但 Apache 是我在 Unix 平台上最佳 web 服务器的首选。

  4. cgi-lib.pl 库(可选):这是一组用于从表单读取输入的 Perl 例程。如果您计划接受来自 web 表单的输入以生成 GIF 图像,则需要此包或类似的包。 cgi-lib.pl 可以从 http://www.bio.cam.ac.uk/cgi-lib/ 免费下载。有类似的软件包可用,但 cgi-lib.pl 是我的个人偏好。

示例 #1

安装完所有软件包后,您就可以创建您的第一个使用 GD.pm 的 CGI 脚本了。

在第一个示例中,我们读入两个 GIF 图像:一个主图像和一个箭头图像。根据用户的输入,我们将箭头“放置”在主图像上。最后,我们显示最终图像。列表 1 显示了此示例的源代码。

第 2 行请求使用 GD 接口,第 3 行验证我们是否正在使用 Perl 5.002 或更高版本。第 5 行包含来自 cgi-lib.pl 的例程,用于读取表单输入。这些例程之一 ReadParse 在第 6 行中使用,以获取表单输入数据。来自此表单的数据存储在名为 FORM 的关联数组中。

接下来,第 8-11 行设置变量,其中包括主图像和箭头图像的文件名。此外,如果未从 web 表单或其他技术提供,则为主图像上箭头的放置变量分配默认值。稍后我将展示一个将变量传递给脚本的示例。

第 13-15 行和 17-19 行执行相同的操作。第一组将主图像读入名为 $main 的变量。第二组读取箭头图像并将图像存储在变量 $arrow 中。在每组中,您都会注意到一个例程 newFromGif GD::Image(GIF)。这是从文件中读取图像并将其存储到变量中的 GD 函数。这个例程的好处是它不需要图像尺寸,尽管您可能想知道它们。

第 21 行完成了脚本中的大部分工作。它将箭头图像存储在主图像上 x 像素位置 $FORM{xp} 和 y 像素位置 $FORM{yp} 处。该函数的最后四个参数定义了复制箭头图像的多少。在我们的例子中,所有箭头图像都被复制到主图像上。

最后,第 23 行和第 24 行输出图像,就像从 HTML 文件中调用一样,第 25 行结束脚本。

现在,我们需要调用脚本来生成图像。您可以通过几种方式执行此操作。首先,只需直接从 Netscape 等 web 浏览器调用 CGI 脚本。URL 示例为 http://bodock.vislab.olemiss.edu/cgi-bin/example1.cgi。

调用脚本将仅在屏幕上显示图像。您还可以将此 URL 放在 HTML 文件的 IMG 标记中,如下所示

<IMG SRC=
"http://bodock.vislab.olemiss.edu/cgi-bin/example1.cgi"
ALT="">

最后,您可以稍微修改 URL 以指定箭头图像的 x,y 位置。IMG 标记中的 URL 示例将如下所示

<IMG SRC="/cgi-bin/example1.cgi?xp=10&yp=40"
alt="">
请注意,我删除了完整的 URL。这样做假设 CGI 脚本与网页在同一台机器上。
示例 #2

下一个示例使用了 GD 接口提供的一些更多功能。我们绘制箭头,而不是从文件中读取它。通过绘制箭头,我们可以控制绘制在主图像上的箭头的角度。列表 2 显示了此示例的源代码。

第 1-8 行应该与前面的示例类似。我们只是为主 GIF 图像和箭头的位置/角度定义变量。为了简单起见,我没有包含 ReadParse 例程,因此不允许用户输入。与第一个示例一样,我们在第 10-12 行中将主图像读入变量 $im

第 15 行是新的。此行仅基于 RGB 值分配颜色,RGB 值的范围为 0 到 255。蓝色具有 RGB 值 (0,0,255)。然后我们可以在稍后绘制箭头时使用该颜色。

第 17 行调用用于创建箭头的函数。此例程从第 26 行开始。在此例程中,我们创建一个新的多边形(一个箭头),然后花费大部分时间查找多边形的点。在我们找到多边形角点的 x,y 位置后,我们将其放入多边形对象 $poly 中。

如前所述,我们的多边形是一个箭头。第 37 行创建多边形变量。然后第 38-44 行查找多边形的点。以下是该部分的工作原理。第 33-34 行定义了指向北方的箭头的 x,y 位置。由于我们可能想要旋转此箭头,因此第 38-44 行开始发挥作用。这些行计算出每个点的新 x,y 位置,同时考虑了旋转角度。第 43 行将点添加到多边形,同时考虑了图像的大小(减去 75)和箭头将放置的 x,y 位置($xpos$ypos)。与其花一整天时间试图解释代码的这一部分,不如看看旧的 CGA 图形书。事实上,我从 CGA 图形手册中获得了本节的公式。

最后,我们有一个多边形存储为变量 $poly,它被返回到主程序。第 19 行是另一个 GD 接口调用,用于用我们的颜色填充箭头并将其放置在主图像上。最后,显示图像并且脚本退出。

与第一个示例一样,您可以直接和通过 IMG 标记调用此 CGI 脚本,如下所示

<IMG SRC=
"http://bodock.vislab.olemiss.edu/cgi-bin/example2.cgi"
ALT="">

如果您想动态控制箭头的角度,您需要修改此示例以包含 cgi-lib.pl 库,使用 ReadParse 读取数据,然后适当地定义 $angle

更多细节

我们现在知道如何动态创建 GIF 图像,并直接和从 HTML 文件中的 IMG 标记查看它。如果您需要保存图像怎么办?

当然,首先您需要一个将要创建图像的目录。根据您的 web 服务器配置,需要修改该目录的所有权和写入权限,以便 CGI 程序可以保存图像。与您的网站管理员讨论此事。

一旦该问题得到解决,您的 CGI 脚本可以使用唯一的文件命名方案将图像输出到文件。要回忆起此文件名,您可以使用数据库或只是将文件名告知客户端。例如,如果您开发一个 CGI 程序来创建虚拟明信片,则唯一需要图像名称的人是明信片的发送者和/或接收者。这可以在创建明信片后在 web 浏览器中显示,或通过电子邮件发送给接收者。在其他情况下,可能需要多人查看图像。在这种情况下,在我看来,使用数据库存储文件名以及相关选项是最佳选择。

无论哪种情况,存储图像都可以在显示图像之外完成。也就是说,只需使用常规 Perl I/O 语句将图像打印到文件即可。拿起任何 Perl 编程书籍并查看文件 I/O 部分。

最后,您可能必须密切关注存储图像的目录。如果文件名是唯一的且图像很大,请考虑定期删除旧文件,以避免每月购买新磁盘。当然,您可能想以此为借口来获得更多的磁盘空间。

更多信息

当然,GD.pm 随附的文档可以填补您可能存在的任何空白。此外,以下是两个 URL,显示了我动态创建 GIF 图像的一些编程工作。第一个是密西西比大学 (UM) 的校园地图。第二个示例重点介绍了我家乡州的一些有趣地点。

对于 UM 校园地图,原始 GIF 创建程序是用 C 编写的,并使用 gd C 库。您可以访问 URL http://www.olemiss.edu/hospitality/maps/ 上的页面。页面顶部的查找选项将带您到其他网页。从那里,您可以选择感兴趣的地点。只需单击鼠标,就会显示校园图像,并带有箭头突出显示您的选择。此外,每个建筑物的所有信息都列在数据库中,因此 CGI 程序必须首先获取此信息,然后才能创建图像。

在 URL http://bodock.vislab.olemiss.edu/onthefly.html 上可以找到动态创建 GIF 图像的更详细示例。这结合了多个选项,例如文本、颜色选择、各种指针等。请务必关注最左侧框架底部的“更多实用示例”链接。该部分显示了同时添加多个文本和突出显示器的示例。此外,由于一些用于客户端图像地图的 HTML 代码,该地图是可点击的。此应用程序的 CGI 程序是使用 Perl 和前面提到的其他软件包开发的。

结束语

与任何开发项目一样,每个人都对要使用的最佳软件包有自己的看法。我对 gd C 库和 GD.pm 接口动态创建 GIF 图像非常满意。根据您的经验和您的 web 服务器平台,您可能会找到其他更适合您需求的软件包或接口。

我唯一的建议最初来自我的父亲,但为九十年代和 GIF 图像创建进行了稍微修改:“当气动棘轮扳手(使用 GD.pm 编程)可以完成工作时,永远不要使用扳手(图像编辑器)。”

Jimmy Ball 是密西西比大学校园内密西西比超级计算研究中心的超级计算机用户顾问。他还兼职担任互联网顾问,专注于 web 开发、Unix 管理和培训。可以通过电子邮件 ccjimmy@mcsr.olemiss.edu 或 jball@ebicom.net 联系 Jimmy。

加载 Disqus 评论