电脑技术学习

自制玩笑版超级轰动新闻

dn001
  最近很多大型网站相继推出了一些玩笑性质的新闻,网友们纷纷转载这些新闻让自己的朋友也感受一下新年的惊喜(图1)。



  这些玩笑新闻能在开始时骗倒网友的原因是新闻中都含有一张图片,图片中有着网友的网名或者姓名,而且又是来自大型门户网站的新闻,所以能起到以假乱真的效果。更有趣的是这些新闻都提供一个输入别人名字的输入框,只要输入朋友的名字,那么整个新闻从图片到文字部分都会依照输入的新名字发生变化(图2)。



  一、基本原理分析

  通常来说,要让网站中的文字根据输入框变化是网页最基本的功能之一,所以使用虚拟主机的个人站点站长可以轻松地做出这样的网页,但是对于图片中的文字内容要根据输入框内容变化,则涉及到绘图的问题。一直以来给图片绘图使用最多的地方都是各种水印和需要即时生成图片的股票走势等应用,对于个人站点的站长,绘图并不是一件容易的事。主要原因不是技术上的,而是可能碰到服务器不支持,或者没有安装某些插件,如果自己有主机的站长,可以考虑使用一些容易的命令行绘图软件,如ImageMagick来进行这个操作,只需在程序脚本中嵌入:

  安装路径convert -font 字体 -fill 颜色 -pointsize 字体大小 -draw 'text 5,15 "文字内容"'

  这个语句就可以使用Image Magick自带的convert程序来进行水印操作,其中text 5,15是文字在图片上左上角开始计算的坐标。ImageMagick的功能非常强大,而且同时支持各种操作系统,所以无论是Windows主机还是Unix类主机,甚至是MacOS等都可以使用。ImageMagick还是免费的开源软件,功能非常强大,甚至可以将它看作是一个具备命令行功能的Photoshop。但是ImageMagick的安装,特别是在Unix类主机下的安装非常麻烦,与很多在Windows系统下ASP程序用来做图的模块一样,它们并不是每一个虚拟主机都会安装的软件。

  二、常规解决方案

  比较综合的考虑,最常见的环境是PHP+GD支持的虚拟主机。即便是Windows主机也基本对PHP提供了支持,不像ASP在Linux环境只能用模拟器来执行。GD库作图长久以来都是被PHP很好支持的,特别是在PHP4.3.0版后。如果默认安装输入了参数--with-gd,那么会从自带程序包里面安装好GD库,无需复杂的手续。但是PHP对于多字节的支持就没有这么好,在4.3.X版后有一套Multi-Byte String Functions,需要在安装的时候加入--enable-mbstring=all等多个参数才能正常使用,一般PHP环境都没有提供对它的支持。假设你已经安装了对它的支持,那么可以在PHP代码中使用如下语句进行GB2313编码到UTF-8编码的转换,当然它还可以用来转换韩文和日文。

  $str = mb_convert_encoding($str, "GB2313", "UTF-8");

  对于一个只有PHP和GD的环境,我们需要一个码表(GB2312.TXT)和一个自定义函数(gb2utf8)来完成这个转码的工作。然后使用GD库的绘制图片代码生成一个带有输入文字的图片,最主要的几行代码如下:

  header ("Content-type: image/pjpeg");
  $photoImage=Image CreateFromJpeg('imgs.jpg');
  ImageAlphaBlending($photoImage, true);
  $info = urlencode(rawurlencode($_GET[info]));
  $info = urldecode(rawurldecode($_GET[info]));
  $font="c:windows ontssimsun.ttc";
  $str=gb2utf8($info);
  $white = imagecolorallocate($photoImage, 255,255,255);
  $black = imagecolorallocate($photoImage, 50,50,50);
  ImageTTFText ($photoImage, 15, 7, 130, 220, $black, $font, $str);
  ImageJPEG($photoImage); // output to browser
  ImageDestroy($photoImage);

  以上代码需要说明的是imgs.jpg是用来绘制文字的原图,simsun.ttc是绘制中文时需要的TTF字库,代码中默认原图在程序所在的目录,而simsun.ttc是采用了Windows系统自带的宋体字库。如果不是在这两个目录,那么都需要给出文件所在的绝对路径,Linux系统中如果没有中文字库,可以将Windows的字库上传到服务器中使用,特别注意的是如果需要输出中文,那么一定需要中文TTF字库,英文字库是不行的,繁体中文也就需要繁体中文的TTF字库。

  最重要的一行代码是:

  ImageTTFText ($photoImage, 15, 7, 130, 220, $black, $font, $str);
  它的函数原型是:
  array imagettftext ( resource image, int size, int angle, int x, int y, int color, string fontfile, string text)
  将字符串 text 画到 image 所代表的图像上,从坐标 x,y(左上角为 0, 0)开始,角度为 angle,颜色为 color,使用 fontfile 所指定的 TrueType 字体文件。

  对于一些想要加字的比较特殊的图片,比如竖立的金条上加字,那么角度值就非常重要,关于GD库函数更多的细节,可以查询PHP说明手册。同时这个生成图片的PHP文件输出的是一张图,还无法直接调用,那么就需要另外一个PHP程序中对输入的文字内容进行处理,并使用<img src=文件名?参数名=参数值>这个html代码来调用生成图片用的PHP文件。最后还可以在这个PHP文件中加上其他一些文字内容,让页面变得更充实,多次让人名出现在文章中,可以更好的迷惑来访者。

  三、网页安全及注意事项

  最后值得一提的是安全问题,因为直接在URL中跟上参数是网页设计比较忌讳的问题,所以在PHP中应该使用系统预定的传输变量$_GET,而不是直接调用变量本身。对于文字输入还需要一定的安全过滤,把一些敏感的关键字也进行屏蔽。在输出图片的PHP文件中,还需要加上一行:

  if(!strstr($HTTP_ REFERER,"另外一个PHP程序的URL地址")) die( "请勿盗链哦,^^" );

  这样这个文件就只能被输出用的程序调用,而不会被盗链,用GD库调用TTF文件来绘图是相当占用系统资源的工作,访问量太大会影响服务器的正常使用。
  知道了原理和方法,现在有条件的读者就可以借新春或情人节之际,给朋友一个让他惊喜的自制玩笑版超级轰动新闻了。

  提示:文中涉及的代码及相关示例文件可在http://www.pcdiget.com/download/下载。