Home > php教程 > php手册 > PHP之图形处理

PHP之图形处理

WBOY
Release: 2016-06-13 09:37:52
Original
1063 people have browsed it

图形处理

 

PHP 的图形处理,主要功能集中在 PHP 的图形处理函数。

 

需要先掌握一些要点。什么叫图片,怎么显示图片。

 

所谓的图片,其实也是一种文件,只是内容不是我们肉眼直接可见的。如果我们用记事本打开一张图片,只会看到一片乱码。其实这些乱码,只是相对我来说是乱码。对于可以读写它的程序来说,一点都不乱。如果我们知道一种图片的格式,我们就可以自己生成一张图片。就像我们最早的时候,制作的记事本留言本一样。

 

把一些特殊格式的数据,保存到一个文件,就可以生成一张图片。反之,我们如果用 PHP 直接输出这些内容,浏览器也会认为这是一张图片。

 

我们先来证实一下这一点,同学们先准备好一张图片。建议小一点的, JPG 格式就可以了。然后我们使用 PHP 读取这张图片,就像普通文件一样读取。

 

 

$file = "1.jpg";

 

$fp = fopen($file, "rb");

$data = fread( $fp, filesize($file));

fclose($fp);

 

echo $data;

?>

 

相信对于同学们来说,这个代码没有什么问题吧。

 

打开文件,读取内容(所有字节),关闭文件,输出内容。

 

有没有同学试一下,这个代码运行后会输出什么,截个图上来看一下。

 

 

也许有同学会奇怪吧,怎么是乱码。

因为浏览器默认,认为我们的 PHP 输出是文本。即使是乱码,我们需要告诉浏览器,这是一张图片。这个需要用 header 函数,发送头信息,告诉浏览器,当前输出的内容,是格片格式。

Header("Content-type: image/jpeg");

这是 JPG 格式图片使用的头信息,内容类型:图片/jpeg,需要加在 echo 之前。

 

 

$file = "1.jpg";

 

$fp = fopen($file, "rb");

$data = fread( $fp, filesize($file));

fclose($fp);

 

Header("Content-type: image/jpeg");

echo $data;

?>

同学们再试一下。

 

这个代码证明了一点:即使输出的是乱码,只要浏览器知道它是什么内容;它就能正确显示。

相对的,如果我们把读出来的内容,保存到另一个文件,就可以复制这张图片。

在这里,可能会有一些同学会有一些误解。认为,这里还是一个网页。各位同学可以试一下,在打开的网页空白处,点一下鼠标右键,查看源文件,会发现,没有这个选项。即使有,也是灰的。这是因为,这个不是一个页面,浏览器已经认为,我们这个 PHP 程序,是一张图片了。

平时我们使用 PHP 进行任何形式的输出时,浏览器认为这是一个 HTML 网页,才能看到源代码。

 

如果我们输出的是图片内容,要能正确显示,就必须告诉浏览器,本次输出,别把我当成网页,而是当成图片。也就是说,我们的 php 程序,是一张图片。如果要想在别的网页使用这张图片,需要像平时一样 PHP之图形处理

PHP之图形处理

把这个 PHP 程序,当成一张图片来对待,而不能直接在这个程序写上。

PHP之图形处理

这样是不对的,这样只会导致一个结果。

PHP之图形处理

这是不可能显示得出来的。

所以,使用 PHP 处理图片的程序,一定是单项功能的 PHP 程序。除非你不输出这张图片,而只是把它保存起来。

 

$file = "1.jpg";

 

$fp = fopen($file, "rb");

$data = fread( $fp, filesize($file));

fclose($fp);

 

$fp = fopen("2.jpg", "wb");

fwrite($fp, $data);

fclose($fp);

 

?>

PHP之图形处理

如果代码是这么写,就是另一回事,没有错。把图片保存到另一个地方,然后输出 HTML 调用这张图片。要直接输出图片的 PHP 程序,一定不可能含有别的输出,没有用。只能单纯的输出图片的内容,就是那堆乱码。

好了,读取图片,输出图片都没有问题了。

 

文件的内容是特殊格式,我们看都看不懂,怎么处理它呢?

PHP 提供了专门的图形处理函数。

 

图形处理函数库,有一个专用的名字,叫 GD库。

 

这个函数库并不是 PHP 自带的。需要在安装 PHP 的时候,在 php.ini 里设置加载。

库文件名叫 php_gd2.dll。PHP 的安装包里就有,在 ext 目录下。如果哪位同学的 php.ini 里还没加载 GD库,请现在打开它。

 

这样,PHP 才有图形处理函数可用。

当前 PHP 自带的 GD 库版本是 2.0.28。PHP 4 带的是 gd 2.0,PHP 3 时代是 gd 1.6。

为什么要提这个呢?

因为 gd 2.0 的时候,因为 GIF 图片的版权问题。PHP 做为免费开源的语言,无法向 GIF 的版权商提供版权费,所以只能暂停对 GIF 图片的支持。PHP 5 以后,GIF 版权到期, 我们的 PHP 才重新支持 gif 图片。

 

好了,我们打开 PHP 手册,看一下 Image 图像函数。

函数很多,但是,大致上可以分成四类:创建,绘画,设置,输出。

 

如果要创建一张图片,可以使用 imagecreate 函数。从函数名就可以看得出来了,创建图像。从手册上,可以看得到语法格式。

 

返回图像资源 imagecreate(宽度 , 高度)

 

宽度和高度以像素为单位。

 

还有另一个函数,imagecreatetruecolor 新建一个真彩色图像,支持更多颜色。

创建类的函数,都会返回一个图片资源,有点类似于 fopen 函数的返回。资源型的数据,内部含有一个可读写指针,,让我们可以对图片进行编辑操作。

 

我们先来试试创建一张图片,先用 imagecreate 函数好了。

为了能看到这张图片,我们需要输出。但是我们的经验告诉我们,资源型的内容不能直接输出。

图片形函数,给我们提供了一些函数,分别是:

 

imagejpeg 以 JPG 格式输出

imagegif  以 GIF 格式输出

imagepng  以 PNG 格式输出

函数格式是一样的。

 

imagejpeg( 图像资源 , [保存路径])

如果需要保存这张图片,就在第二个参数写上文件名就可以了。如果只是希望直接输出,第二个参数不写就行。

我们现在先直接输出这张图像。

Header("Content-type: image/JPEG");

 

$img =imagecreate(100, 100);

imagejpeg($img);

创建一张 100*100 的图像,然后用 JPG 格式输出它。要记得告诉浏览器,这是图片。

运行的结果是什么样的呢?有哪位同学截个图上来看看。

 

是的,会输出一张黑色的图片。因为我们并没有在上面画任何内容,也没告诉它应该用什么颜色。

我们先来简单一点的操作,先在上面涂点颜色。这个需要使用 imagecolorallocate 函数。

 

函数功能是:为一幅图像分配颜色

函数格式是

 

imagecolorallocate(图像资源, 红色,绿色,蓝色)

三元色,分别用 0 到 255 的数字表示。0是最暗,255是最亮。如果需要白色,三色都是 255 就可以了,黑色就是三色 0,如果只要红色,就是 255 0 0。

header("Content-type: image/jpeg");

 

$img =imagecreate(100, 100);

imagecolorallocate($img, 255,0,0);

imagejpeg($img);

我就填上个纯红好了。同学们可以自己试试,分别给红绿蓝设置一些数值,看看结果如何。这个配色,需要一些知识了。同学们也可以直接在各种画图工具里得到这个颜色。

 

右下角的 红绿蓝 值就可以直接用。很多软件都有类似的调色板,很容易可以得到各种颜色值。

这里有一点要注意。

imagecolorallocate 函数,只有第一次使用的时候,会给图像填上背景色,重新使用,并不会改变背景色。

header("Content-type: image/jpeg");

 

$img =imagecreate(100, 100);

imagecolorallocate($img, 255,0,0);

imagecolorallocate($img, 0, 0, 255);

imagejpeg($img);

这个代码,并不会输出预期的蓝色。但是,并不表示函数没有用。函数依然有效,只是这个颜色没有被使用而已。我们可以用这个颜色,做其他用途,比如写字。

 

我们来试试,在图像上面写点字。

PHP 给我们提供的函数里面,有两个函数可以用于在图像上写字,分别是 imagestring  和 imagestringup。

imagestring  是横向写字

imagestringup 是纵向写字

如果用 imagestringup 写的话,我就们看字就得扭着脖子看了。好吧,先用 imagestring。

 

imagestring 函数原型

 

imagestring(图像资源, 字体, 开始X坐标,开始Y坐标, 要写的字, 颜色)

PHP 自带的字体只有5种,需要用数字1到5表示。

我们来试一下吧。

header("Content-type: image/jpeg");

 

$img =imagecreate(100, 100);

imagecolorallocate($img, 255,0,0);

 

$color = imagecolorallocate($img, 0, 0, 255);

imagestring($img, 4, 0,0, 'abcdef', $color);

 

imagejpeg($img);

 

你大爷的,好刺眼,我换白底好一点。

有没有哪个同学试试写个中文?结果会让人很失望。

 

因为 PHP 自带的字体,弱爆了,跟本无法正常显示中文。怎么办呢?

自定义字体。

image 函数,给我们提供了另一个函数,可以使用自定义字体来写字。严格来说是“画字”。需要一个带点阵格式的字体文件,而且要支持中文的,最常见的就是 ttf 类型的字体了。如果做过平面设计的同学,对这个一定不陌生,没做过的同学,也不要紧。我们可以在我们的系统里面,挖几个出来用用。系统自带的字体文件,在 C:\windows\fonts 目录,我们可以在里面找一个支持中文的字体。WIN 系统自带的字体,大多数都支持中文,我挑一个微软雅黑。回到我们的 PHP。

要使用这个字体文件来画字,需要用 imagettftext 函数。

 

imagettftext 函数原型

 

imagettftext (图像资源, 字体大小, 字体方向, 开始X坐标, 开始Y坐, 字体颜色, 字体文件, 要写的字 )

我的娘哦,好多参数。估计各位同学也是第一次用这么多参数的函数吧。

 

//创建图片,并设置白底

$img =imagecreate(100, 100);

imagecolorallocate($img, 255,255,255);

 

//准备一个颜色,

$color = imagecolorallocate($img, 0, 0, 255);

 

//准备一个字体文件

$font = "msyhbd.ttf";

 

//图像资源, 字体大小, 字体方向, 开始X坐标, 开始Y坐, 字体颜色, 字体文件, 要写的字

imagettftext($img, 14, 0, 20, 20, $color, $font, "中文支持");

 

//JPG格式输出图像

imagejpeg($img);

这个图像文件,如果路径不在当前目录下,要告诉 PHP 在哪里。

比如 $font = "./font/msyhbd.ttf";

或者 $font = "C:\\windows\\fonts\\msyhbd.ttf";

必须让 PHP 找得到这个字体文件

 

imagettftext($img, 14, 180, 150, 150, $color, $font, "中文支持");

 

字体方向 180度,结果就成这样子。另外,中文在这里必须是 utf8 编码。这个很容易做到,把 PHP 文件转换成 utf8 编码就可以了。使用 gbk 编码的同学,可以给字体转换一下编码。

$text = iconv("gbk", "utf-8", "中文支持");

只要有足够的字体,我们可以让 PHP 输出任意样式

$font = "FZKANGFW.TTF";

$text = iconv("gbk", "utf-8", "中文支持");

imagettftext($img, 20, 0, 150, 150, $color, $font, $text);

 

这个效果,配合预定变量 $_SERVER 可以做到一个效果。

 

$_SERVER['REMOTE_ADDR']

 

这个服务器变量,可以得到来访者的 IP 地址。网上的各种带 IP 显示的图片,就是这么做出来的。不就是在图片上写几个字么。

 

 

好了。然后我们来学习一下。在上面画线条。

 

画图函数很多。

imagedashedline - 画一虚线

imagedestroy - 销毁一图像

imageellipse - 画一个椭圆

imagefill - 区域填充

imagefilledarc - 画一椭圆弧且填充

imagefilledellipse - 画一椭圆并填充

imagefilledpolygon - 画一多边形并填充

imagefilledrectangle - 画一矩形并填充

画线是 imageline,其他画图函数,同学们可以自行参考手册。

看来看去,不外乎原理就是:在图像资源上,用什么颜色,从哪个坐标开始,画什么。

 

imageline函数原型

 

( 图像资料, 开始X坐标, 开始Y坐标, 结束X坐标, 结束Y坐标, 颜色 )

 

在数学中,我们知道XY坐标可以确定平面上的一个点,两个点可以决定一个线段。

 

//创建图片,并设置白底

$img =imagecreate(300, 300);

imagecolorallocate($img, 200,200,200);

 

//准备一个颜色,

$color = imagecolorallocate($img, 0, 0, 255);

 

//用这个颜色画一条线

imageline($img, 0,150,  300,150,  $color);

 

//JPG格式输出图像

imagejpeg($img);

我的图像是 300*300 的大小。从0,150 就是最左边,中间位置,到最右边,中间位置。

 

如果要画一张网格的话,你就慢慢算座标,然后重复画就可以了。

 

for($i=0; $i

    $y = $i*50;

    imageline($img, 0,$y,  300,$y,  $color);

}

竖线什么的,就不多说了。

还有其他各种线条,形状,各位同学可以跟据手册的说明,自行练习。

 

 

很多时候,我们图片是现成的。我们要做的只是缩小,裁剪大小。

图片是现成的,我们需要把图片加载进来,跟据图片的不同类型,我们需要不同的函数来加载。

imagecreatefromjpeg 创建一张图像,来自JPG文件

imagecreatefromgif  GIF

imagecreatefrompng  PNG

imagecreatefromwbmp WBMP

imagecreatefromxbm  XBM

图片是什么类型,就用什么函数来载入。这些函数,都属于创建类函数。之前,我们使用写字,画线,都属于绘画类函数。这样区分,就不觉得函数多了。很多函数其实是重复的,只是针对于不同的类型。所有的操作,都是针对于画布,在画布上画什么。

 

其实 PHP 并不能缩小一张图片,那只是一种思路上的技巧。用的是图像复制函数imagecopymerge。

可以把图像的一部份,复制到另一张图像上面,同类的还有另一个函数imagecopyresampled。都是复制图像的一部份,复制到另一张图像上面。这意味着,这样的操作,需要两个图像。一个是原图,一个是新生成的图。

 

原图,我们可以用 imagefrom 系列函数加载进来。新图,我们可以自己创建。然后再使用图像复制函数,从原图复制到新图。

如果复制的只是其中的一个区域,那就是 裁剪功能。如果复制是整个图像大小,新图的大小和原图大小不同,就是改变图片大小,也就是缩略图,或者放大图。

$image = "1.jpg";

//读取图片大小

list($width, $height) = getimagesize($image);

 

//加载图片

$bimg = imagecreatefromjpeg($image);

 

//新建图片,大小是原图的一半

$simg =imagecreatetruecolor($width * 0.5, $height * 0.5);

 

//在原图上,把原图的全部,缩小一半,复制过来

imagecopyresampled($simg, $bimg, 0,0, 0,0, $width*0.5, $height*0.5, $width, $height );

 

//JPG格式输出小图像

imagejpeg($simg);

应该有同学发现了,这里使用的是 imagecreatetruecolor 创建新图像。真彩图像,而不是 imagecreate。同学们可以试一下,用 imagecreate 是什么结果。

复制图像,我选择了 imagecopyresampled 函数,复制并调整大小。同类函数还有 imagecopyresized。

 

imagecopyresized

imagecopyresampled

 

这两个函数都是复制并调整大小图像。同学们可以自己测试它们的区别。由于参数太多,我这里帮你们做一个注释。

 

新图, 原图,

新图起点X,新图起点Y,

原图起点X,原图起点Y,

新图宽度,新图高度,

原图宽度,原图高度

 

两个一组,一起看就行了。

 

//加载图片

$bimg = imagecreatefromjpeg($image);

 

//新建图片,大小是原图的一半

$simg =imagecreatetruecolor($width * 0.5, $height * 0.5);

 

//在原图上,把原图的全部,缩小一半,复制过来

imagecopyresampled($simg, $bimg, 0,0, $width*0.5, $height*0.5, $width, $height, $width, $height );

这个代码的意思是

 

$simg, $bimg,  //新图,原图

0,0,  //从新图的 0*0 开始画

$width*0.5, $height*0.5, //从原图的中心点取样

$width, $height, //新图和原图等大小。

$width, $height  //到原图的最右下角坐标结束

由于创建的图像只有原图的一半,这个代码,会使得最终图片只显示原图中心点开始。右下角的内容。也就是 1/4 原图的内容,就是所谓的裁剪。

 

这些函数的参数太多,不太容易看,计算各个采样坐标,需要更细心。

 

水印图的原理也是一样的。加载两张图,创建两个图像对象。然后把水印图,复制到原图上。面。其实都只是一个思路的技巧而已。

 

图形函数就讲到这里。

 

我先来总结一下这一课的要点。

1、一定要先创建图像,加载创建或自己创建。

2、只能在图像上面绘画,线条,形状

3、文字只能用 UTF8 编码,要显示中文需要中文字体

4、图像本身不能直接调整,只能在复制的过程中调整。

5、如果要直接输出图像,这个程序不能输出其他多余的东西

6、一个直接输出图像的程序,要把它看成图片来调用。

 

图像函数。分为几类:

创建类:imagecreate、imagecreatefromjpeg

设置类:imagecolorallocate、getimagesize

绘制类:imagecopyresampled、imageline、imagettftext

输出类:imagejpeg、imagepng

 

其中绘制类的函数最多,函数格式也很相似,都是:

在图像的XX坐标,绘制XX东西

 

复制操作的函数,坐标往往有8个之多。

原图起点坐标,原图宽高, 这就四个了;

新图起点坐标,新图宽高, 这里又四个;

再加上原图,新图。有十来个参数。

 

所以,一般图像处理的过程,往往调试好一个程序之后,都不愿意再回头重新改了。封装成自定义函数吧。

比如缩略图函数。

 

function size_img($img, $width, $height) {

   中间你就处理吧。

}

这样提供一个图片,指定输出的大小,就可以生成缩略图了。至少用起来方便多了。

 

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Recommendations
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template