侯体宗的博客
  • 首页
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

php 图像函数大举例(非原创)

php  /  管理员 发布于 7年前   151

如下方式是一种方法:
if(!function_exists('imagecreate')) {
die('本服务器不支持GD模块');
}
如果不支持的话,如何配置 ? 下载gd模块的dll文件,修改php.ini,重启服务器即可.
以下简称PHP作图为PS.
当您打算 PS的话,应该完成如下如下步骤,这是必经的.
1:创建基本PS对象(我假设为$image),填充背景(默认黑),以后的全部ps操作都是基于这个背景图像的.
2:在$image上作图.
3:输出这个图像.
4:销毁对象,清除使用内存.
首先,我们来认识几个常用的函数,这些函数在php手册里面都有详细介绍,此处大体引用下.
resource imagecreate ( int x_size, int y_size )
imagecreate() 返回一个图像标识符,代表了一幅大小为 x_size 和 y_size 的空白图像。
此函数基本同imagetruecolor($width,$height).
---------------------------------------------------------
int imagecolorallocate ( resource image, int red, int green, int blue )
imagecolorallocate() 返回一个标识符,代表了由给定的 RGB 成分组成的颜色。image 参数是 imagecreatetruecolor() 函数的返回值。red,green 和 blue 分别是所需要的颜色的红,绿,蓝成分。这些参数是 0 到 255 的整数或者十六进制的 0x00 到 0xFF。imagecolorallocate() 必须被调用以创建每一种用在 image 所代表的图像中的颜色。
---------------------------------------------------------
bool imagefill ( resource image, int x, int y, int color )
imagefill() 在 image 图像的坐标 x,y(图像左上角为 0, 0)处用 color 颜色执行区域填充(即与 x, y 点颜色相同且相邻的点都会被填充)。
---------------------------------------------------------
bool imageline ( resource image, int x1, int y1, int x2, int y2, int color )
imageline() 用 color 颜色在图像 image 中从坐标 x1,y1 到 x2,y2(图像左上角为 0, 0)画一条线段。
---------------------------------------------------------
bool imagestring ( resource image, int font, int x, int y, string s, int col )
imagestring() 用 col 颜色将字符串 s 画到 image 所代表的图像的 x,y 坐标处(这是字符串左上角坐标,整幅图像的左上角为 0,0)。如果 font 是 1,2,3,4 或 5,则使用内置字体。
---------------------------------------------------------
array imagettftext ( resource image, float size, float angle, int x, int y, int color, string fontfile, string text )
本函数比较重要,参数较多,此处不再列出,它主要是写字到图像上,和上面的函数类似,但必前者强大.
---------------------------------------------------------
bool imagefilltoborder ( resource image, int x, int y, int border, int color )
imagefilltoborder() 从 x,y(图像左上角为 0, 0)点开始用 color 颜色执行区域填充,直到碰到颜色为 border 的边界为止。【注:边界内的所有颜色都会被填充。如果指定的边界色和该点颜色相同,则没有填充。如果图像中没有该边界色,则整幅图像都会被填充。】
------------------------------------------------
bool imagefilledellipse ( resource image, int cx, int cy, int w, int h, int color )
imagefilledellipse() 在 image 所代表的图像中以 cx,cy(图像左上角为 0, 0)为中心画一个椭圆。w 和 h 分别指定了椭圆的宽和高。椭圆用 color 颜色填充。如果成功则返回 TRUE,失败则返回 FALSE。
=================================================
输出图像数据:imagepng($image[,$filename])
======================================================
例一:输出蓝色背景和交叉白线的图形
$width=35;
$height=35;
//创建对象
$image=imagecreate($width,$height);
//提取颜色
$color_white=imagecolorallocate($image,255,255,255);//白色
$color_blue=imagecolorallocate($image,0,0,108);//蓝色
imagefill($image,0,0,$color_blue);
//作图
//线宽
imagesetthickness($image,3);
imageline($image,0,0,$width,$height ,$color_white);
imageline($image,$width,0,0,$height ,$color_white);
//发送对象至头
header('content-type:image/png');
imagepng($image);
/*
//发送对象至文件
$filename="ex1.png";
imagepng($image,$filename);
*/
//销毁对象
imagedestroy($image);
?>
输出图像:
在线演示:http://www.phzzy.org/temp/5do8/ex1.php
例二: 阴阳图
$width=400;
$height=400;
$image=imagecreatetruecolor($width,$height);
//提取颜色
$color_black=imagecolorallocate($image,0,2,0);//
$color_white=imagecolorallocate($image,255,255,255);//白色
$color_blue=imagecolorallocate($image,0,0,108);//蓝色
$color_red=imagecolorallocate($image,151,0,4);//红色
$color_my=imagecolorallocate($image,192,192,255);//背景
$color_temp=imagecolorallocate($image,199,199,199);//背景
//作图
imagefill($image,0,0,$color_white);
//第一个是大圆
imagefilledarc ($image,$width/2,$height/2,$height,$height,0,360,$color_blue,IMG_ARC_PIE);
//两个小圆
imagefilledellipse ($image,$width/2,$height/4 ,$height/2,$height/2,$color_red);
imagefilledellipse ($image,$width/2,$height/4 * 3,$height/2,$height/2,$color_blue);
/*imagefilledellipse -- 画一椭圆并填充*/
imagefilledarc ($image,$width/2,$height/2,$height,$height,-90,90,$color_red,IMG_ARC_PIE);
imagefilledellipse ($image,$width/2,$height/4 * 3,$height/2,$height/2,$color_blue);
//发送对象至头
header('content-type:image/png');
imagepng($image);
/*
//发送对象至文件
$filename="ex1.png";
imagepng($image,$filename);
*/
//销毁对象
imagedestroy($image);
?>
演示:
http://www.phzzy.org/temp/5do8/ex2.php
例三:3D图像--cool
$width=400;
$height=400;
$image = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF);
$gray = imagecolorallocate($image, 0xC0, 0xC0, 0xC0);
$darkgray = imagecolorallocate($image, 0x90, 0x90, 0x90);
$navy = imagecolorallocate($image, 0x00, 0x00, 0x80);
$darknavy = imagecolorallocate($image, 0x00, 0x00, 0x50);
$red = imagecolorallocate($image, 0xFF, 0x00, 0x00);
$darkred = imagecolorallocate($image, 0x90, 0x00, 0x00);
imagefill($image,0,0,$white);
// make the 3D effect
for ($i = $height /2 +20; $i > $height /2; $i--) {
imagefilledarc($image, $width/2, $i, $width/2, $height /2, 0, 45, $darknavy, IMG_ARC_PIE);
imagefilledarc($image, $width/2, $i, $width/2, $height /2, 45, 75 , $darkgray, IMG_ARC_PIE);
imagefilledarc($image, $width/2, $i, $width/2, $height /2, 75, 360 , $darkred, IMG_ARC_PIE);
}
imagefilledarc($image, $width/2, $height /2, $width/2, $height /2, 0, 45, $navy, IMG_ARC_PIE);
imagefilledarc($image, $width/2, $height /2, $width/2, $height /2, 45, 75 , $gray, IMG_ARC_PIE);
imagefilledarc($image, $width/2, $height /2, $width/2, $height /2, 75, 360 , $red, IMG_ARC_PIE);
// flush image
header('Content-type: image/png');
imagepng($image);
imagedestroy($image);
/*
//发送对象至文件
$filename="ex1.png";
imagepng($image,$filename);
*/
?>
输出:
演示:http://www.phzzy.org/temp/5do8/ex3.php

例四:简单的验证码
PHP创建验证码非常容易,容易的要死,简单的思路是这样的:
随机种子生成,提取随机字符,相连打印到图形,输出.,为了防止色盲,可以随机提取颜色,也可以自定义颜色,下面看看:
session_start();
$width=65;
$height=20;
$sourcestrings="0123456789aqwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
$image=imagecreate($width,$height);
$colorarrs=array(
imagecolorallocate($image,255,255,255),//white
imagecolorallocate($image,0 ,0 , 0)//black
);
unset($sessionval);
imagesetthickness($image,3);
//随机得到字符串个数
$strsize=rand(3,5);
imagefill($image,0,0,$colorarrs[0]);
//一个个的写字符串到图片
for($i=0;$i<$strsize;$i++){
$i_temp=rand(1,62);
$sessionval .=$sourcestrings[$i_temp];
$fontcolor=imagecolorallocate($image,rand(0,255),rand(0,255),rand(0,255));
$y_i = $height/2 + $font_size /3 ;
imagechar($image,5, 1+ $i * $width /$strsize,5,$sourcestrings[$i_temp],$fontcolor);
}
//写入session,以后验证用
unset($_SESSION['cjjer']);
$_SESSION['cjjer'] = $sessionval;
//添加杂点
for($i=0;$i<$width /$height *2;$i++)
{ $i_x=rand(0,$width);
$i_y=rand(0,$height);
$pixelcolor=imagecolorallocate($image,rand(0,255),rand(0,255),rand(0,255));
imagesetpixel($image,$i_x,$i_y,$pixelcolor);
}
header('content-type:image/png');
imagepng($image);
imagedestroy($image);
?>
生成的样式演示:
在线演示:http://www.phzzy.org/temp/5do8/ex4_login.php
有个很明显的问题就是生成的图片不够艳丽,从而很多的用户看起来不清楚,这样吧,我们自己设定几个比较艳丽的颜色然后输出,扩展colorarrs数组:
$colorarrs=array(
imagecolorallocate($image,255,255,255),
imagecolorallocate($image,0,0,0),
imagecolorallocate($image,0,70,0),
imagecolorallocate($image,92,0,12),
imagecolorallocate($image,0,0,128),
imagecolorallocate($image,233,10,216)
);
然后把23行变为(17行):
$fontcolor=$colorarrs[rand(1,count($colorarrs)-1)];
输出:
在线演示:http://www.phzzy.org/temp/5do8/ex5_login.php
例五:大点的比较cool的验证码
PS 的图像还是比较小的,有时候为了某些原因(个人站点为了玩cool,just我,商业站点玩风格,吸引用户,just google,后话),验证码不是局限于十几个px的限制,有时候完全可以整个2百多,没啥问题,这时候,一种方案是把前面生成的小图强制大点,可以不? 可以,但是,看起来不够光滑,这是事实,明显,宽带不再是最重要的问题,不说其他的,下面演示几个比较好看的生成方式:
session_start();
$width=600;
$height=100;
if($height < $width /6)
$height=$width / 4;
$sourcestrings="0123456789aqwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
//创建对象
$image=imagecreate($width,$height);
$white=imagecolorallocate($image,255,255,255);
imagefill($image,0,0,$white);
//加载字体库
$fonts= dirname(__FILE__);
putenv('"gdfontpath=".$fonts=.""');
$fontname='arial';
$font_size=floor($height / 2);
//得到字符串
unset($sessionval);
$strsize=rand(5,8);
for($i=0;$i<$strsize;$i++){
$i_temp=rand(1,62);
$sessionval .=$sourcestrings[$i_temp];
$x_i =$font_size + $i *$width / ($strsize+1);
$y_i = $height / 2;
$angle_i=rand(-120,120);
$fontcolor_a=imagecolorallocate($image,rand(0,255),rand(0,255),rand(0,255));
imageTTFText($image,$font_size,$angle_i,$x_i,$y_i,$fontcolor_a,$fontname,$sourcestrings[$i_temp]);
}
unset($_SESSION['cjjer']);
$_SESSION['cjjer'] = $sessionval;
//杂点数目
for($i=0;$i<$width * $height / 100;$i++)
{
$i_x=rand(0,$width);
$i_y=rand(0,$height);
imagesetpixel($image,$i_x,$i_y,imagecolorallocate($image,rand(0,255),rand(0,2550),rand(0,255)));
}
//发送对象
header('content-type:image/png');
imagepng($image);
imagedestroy($image);
?>

在线测试: http://www.phzzy.org/temp/5do8/ex6_login.php
解释性说明:
首先是宽和高,高太小字都看不清楚.随机提取的字符还是那么几个:
$sourcestrings="0123456789aqwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
创建对象,填充成白色:
$image=imagecreate($width,$height);
$white=imagecolorallocate($image,255,255,255);
imagefill($image,0,0,$white);
然后加载您要验证码的字体:
$fonts= dirname(__FILE__);//返回当前根目录,字体文件复制到这里,字体文件是*.ttf文件
putenv('"gdfontpath=".$fonts=.""');
$fontname='arial';
定义字符的高度,这里我设置成高度的一半:
$font_size=floor($height / 2);
清除变量,随机设置要生成字符的个数:
unset($sessionval);
$strsize=rand(5,8);
循环,一个个的把字符打上去:
得到本次循环的字符串.,并加在变量后面一会儿写入session
$i_temp=rand(1,62);
$sessionval .=$sourcestrings[$i_temp];
得到写入图像的字符串的位置(x和y坐标)
$x_i =$font_size + $i *$width / ($strsize+1);
$y_i = $height / 2;
设置倾斜度,是从正面看的,.
$angle_i=rand(-120,120);
随机生成颜色,
$fontcolor_a=imagecolorallocate($image,rand(0,255),rand(0,255),rand(0,255));
写入到图像;
imageTTFText($image,$font_size,$angle_i,$x_i,$y_i,$fontcolor_a,$fontname,$sourcestrings[$i_temp]);
如果对此函数存在疑问,请查阅相关资料.非常容易.
写入到session,一边注册码使用:
unset($_SESSION['cjjer']);
$_SESSION['cjjer'] = $sessionval;
添加杂点:
//杂点数目
for($i=0;$i<$width * $height / 100;$i++)
{
$i_x=rand(0,$width);
$i_y=rand(0,$height);
imagesetpixel($image,$i_x,$i_y,imagecolorallocate($image,rand(0,255),rand(0,2550),rand(0,255)));
}
输出到头:
header('content-type:image/png');//这行表明是png图像,可不要,默认可以输出的.但不是图像的头格式
imagepng($image);
imagedestroy($image);
你可以加载你自己的字体库,设置旋转角度$angle_i=rand(-120,120);设置字体高度$font_size=floor($height / 2);字体颜色$fontcolor_a和随机数的个数:$strsize=rand(5,8);

例六:给图片打上水印,生成缩列图
传统的ASP页子打水印和生成缩列图都是比较繁琐的,一般使用到的是其他组件什么的,但是,PHP可以轻松的干这些事情,正如您预料,不到30行的程序搞定这一切,请看这个源程序:
$source="my.jpg";
$zoom=0.5;
$str='我是帅哥,你是MM么?';
$image=imagecreatefromjpeg($source);
$width=imagesx($image);
$height=imagesy($image);
$color_red=imagecolorallocate($image,111,0,0);//红色
$font=dirname(__FILE__). "//simsun.ttc";
$str=iconv('GB2312','UTF-8',$str);
$fontsize=30;
$angle=25;
$fromx=$width/5;
$fromy=$height/2;
imagettftext($image,$fontsize,$angle,$fromx,$fromy,$color_red,$font,$str);
$width_temp=imagesx($image) * $zoom;
$height_temp=imagesy($image) * $zoom;
$img=imagecreatetruecolor($width_temp,$height_temp);
imagecopyresized ($img,$image,0,0,0,0,$width_temp, $height_temp,$width,$height);
imagedestroy($image);
$file_zoomname="my_zoom_jpeg.jpg";
imagejpeg($img,$file_zoomname);
imagedestroy($img);
?>
原始图片:
生成的jpg图片:
原始图片70K, 这里说下,如果生成gif,文件18k多,而png要用去76k,so我们生成缩列图用jpeg格式.
代码分析:
这里我先设置了几个参数:
$source="my.jpg"; //源图片
$zoom=0.5; //缩放百分比
$str='我是帅哥,你是MM么?'; //水印的文字
装载源图(不打水印不装载):
$image=imagecreatefromjpeg($source);
获取长,宽的大小:
$width=imagesx($image);
$height=imagesy($image);
设置水印字体,因为我们用的是中文,必须导入中文字体库,否则写不上或乱码,然后必须转换字符串编码
$font=dirname(__FILE__). "//simsun.ttc";
$str=iconv('GB2312','UTF-8',$str);
设置开始点,字体大小,视角:,写上字符串:
$fontsize=30;
$angle=25;
$fromx=$width/5;
$fromy=$height/2;
imagettftext($image,$fontsize,$angle,$fromx,$fromy,$color_red,$font,$str);
按照缩放的大小要求生成新大小的对象:
$width_temp=imagesx($image) * $zoom;
$height_temp=imagesy($image) * $zoom;
$img=imagecreatetruecolor($width_temp,$height_temp);
把源图copy到新图,gd库的imagecopyresized自动缩放大小的
imagecopyresized ($img,$image,0,0,0,0,$width_temp, $height_temp,$width,$height);
生成小图片,清除对象:
imagedestroy($image);
$file_zoomname="my_zoom_jpeg.jpg";
imagejpeg($img,$file_zoomname);
imagedestroy($img);
生成缩洌图,水印大体核心技术就这么点.


  • 上一条:
    PHP 输出缓存详解
    下一条:
    PHP 类型转换函数intval
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • 用Time Warden监控PHP中的代码处理时间(0个评论)
    • 在PHP中使用array_pop + yield实现读取超大型目录功能示例(0个评论)
    • Property Hooks RFC在PHP 8.4中越来越接近现实(0个评论)
    • 近期文章
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(95个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-06
    • 2017-07
    • 2017-08
    • 2017-09
    • 2017-11
    • 2017-12
    • 2018-01
    • 2018-02
    • 2018-03
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-09
    • 2021-02
    • 2021-03
    • 2021-04
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    • 2024-05
    • 2024-06
    • 2024-07
    • 2024-09
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客