php 缩略图生成类,支持imagemagick及gd库两种处理

PHP的GD库GD函数详解-创建图像 

php文字水印用imagettftext做,如何计算文字所占宽高

php如何发送邮件

 

ImageMagick 安装配置

功能:
1.按比例缩小/放大
2.填充背景色
3.按区域裁剪
4.添加水印,包括水印的位置,透明度等

安装 ImageMagick

0. 下载ImageMagick
http://www.imagemagick.org/download/

下载 ImageMagick-6.9.1-9.tar.gz

1. 开始进行安装

tar xzvf ImageMagick-6.9.1-9.tar.gz

2. 安装第三方图片库
ImageMagick在处理图片时需要依赖jpeg,png等第三方图片库。
第三方图片库下载地址:http://www.imagemagick.org/download/delegates/

下载 jpegsrc.v9.tar.gz

gunzip jepgsrc.v9.tar.gz  
tar -xvf jpegsrc.v9.tar  
cd jpeg-9  
sudo ./configure  
sudo make  
sudo make test  
sudo make -n install

3. 安装ImageMagick

cd ImageMagick-6.9.1-9
sudo ./configure  
sudo make  
sudo make install

安装成功后,使用命令 convert -version 查看是否安装成功。

如出现 error while loading shared libraries,请看这里解决:

运行程式時,如遇到像下列這種錯誤:
./tests: error while loading shared libraries: xxx.so.0:cannot open shared object file: No such file or directory

这表示系統不知道 xxx.so 放在哪個目錄下。這個時候就要在/etc/ld.so.conf中加入xxx.so所在的目錄

一般而言,有很多so檔會在/usr/local/lib這個目錄下,所以在 /etc/ld.so.conf 中加入 /usr/local/lib 這一行,可以解決此問題。

/etc/ld.so.conf  加入后的格式:

# cat /etc/ld.so.conf
include /etc/ld.so.conf.d/*.conf
include /usr/local/lib

將 /etc/ld.so.conf存檔後,還要執行 /sbin/ldconfig –v 來更新一下才會生效。

 

GD 安装配置

开启gd库支持有以下几种方法

检测GD库是否安装命令

php5 -m | grep -i gd   或者    php -i | grep -i --color gd

如未安装GD库,则为服务器安装,方法如下

1) 如果是源码安装,则加入参数 --with-gd

2) 如果是debian系的linux系统,用apt-get安装

sudo  apt-get  install  php5-gd

3) 如果是CentOS系的系统,用yum安装

yum  -y   install  php-gd  或   yum install gd gd-devel php-gd

4) 如果是suse系的linux系统,用yast安装

yast  -i  php5_gd

5) 或者编译PHP不支持GD的情况下附加

先下zlib源码,libpng源码,gd源码

解压后到源码目录 zlib目录

./configure --prefix=/usr/local/zlib

make ; make install

make clean

libpng目录

cp scripts/makefile.linux ./makefile ./configure --prefix=/usr/local/libpng make ;

make install make clean

gd目录

./configure --prefix=/usr/local/libgd --with-png=/usr/local/libpng

make

make install

make clean

最后在php.ini中,搜到[gd]后,在下面加一行 extension=/usr/local/libgdgd.so

然后重启php服务,如果不行,试试reboot 所以如果是源码安装,最好还是在编译PHP的时候加参数--with-gd

6) Windows下开启PHP的GD库支持

找到php.ini,打开内容,

找到: ;extension=php_gd2.dll 把最前面的分号“;”去掉,再保存即可,

如果本来就没有分号,那就是已经开启了。

php-generating-png-picture-code-02

2024.06月新安装的 gd 如下:

错误处理: Call to undefined function ImageTTFBBox

原因分析: This function requires both the GD library and the FreeType library. stackoverflow

解决方案:

1. yum  -y  install freetype freetype-devel

2. 进入php源文件的gd库目录: cd  /opt/php-5.6.11/ext/gd/

3. 加入freetype编译:

./configure  --with-php-config=/usr/local/php/bin/php-config --with-freetype-dir=/usr/include/freetype2/freetype --enable-gd-native-ttf

注意: /usr/local/php/bin/php-config 和 /usr/include/freetype2/freetype 要对应你的安装目录路径

 

freetype 编译安装

1. 下载 freetype : freetype-2.8.tar.gz

2. 编译安装

tar zxvf freetype-2.8.tar.gz
sudo mv freetype-2.8 /opt/
cd /opt/freetype-2.8/
./configure --prefix=/usr/local/freetype
sudo make
sudo make install

解决后的自动生成图片,成功实例请见:米扑代理

本PHP程序作用是从数据库中读取出手机号码或其他数据并生成图片,起到干扰采集防采集的作用。

(英文或数字,如果要支持中文的话需要额外添加字库)。

<?php //前面不要有空行 
$id=$_GET[id]; 
include("admin/config.php"); 
$sql="select * from user where id=$id"; 
$data=mysql_fetch_array(mysql_query($sql)); 
$p=SBC_DBC($data[Phone],1); 
function get_str($str,$strlen=16) { 
$str=stripslashes($str); 
for($i=0;$i<$strlen;$i++) 
if(ord(substr($str,$i,1))>0xa0) $j++; 
if($j%2!=0) $strlen++; 
$tmp_str=substr($str,0,$strlen); 
return $tmp_str; 
} 
if($p<>''){ 
//生成5位的数字图片 
Header("Content-type:image/png"); //告诉浏览器,下面的数据是图片,而不要按文字显示 

//定义图片宽高 
$nwidth=120; 
$nheight=25; 
$im=@imagecreate($nwidth,$nheight) or die("Can't initialize new GD image stream"); //建立图象 

//图片色彩设置 
$background_color=imagecolorallocate($im,255,255,255); //匹配颜色 
$text_color=imagecolorallocate($im,23,14,91); 

//绘制图片边框 
imagefilledrectangle($im,0,0,$nwidth-1,$nheight-1,$background); //矩形区域着色 
imagerectangle($im,0,0,$nwidth-1,$nheight-1,$background_color); //绘制矩形 

//srand((double)microtime()*1000000); //取得目前时间的百万分之一秒值,以执行时的百万分之一秒当乱数种子 
//$randval=rand(); 
$randval=$p; //5位数 
imagestring($im,8,10,2,$randval,$text_color); //绘制横式字串 


//加入干扰元素,例如:像素(pixel)、划线(line)
//for($i=0;$i<478;$i++) 
//{ 
//$randcolor=imagecolorallocate($im,rand(0,255),rand(0,255),rand(0,255)); 
//imagesetpixel($im,rand()%100,rand()%30,$randcolor); //点 
//} 
//imagestring($im,3,5,5,"A Simple Text String",$text_color); 
//imageinterlace($im,1); 
imagepng($im); //建立png图型 
imagedestroy($im); //结束图型 

}else{ 
echo "<font size=2>商家未输入电话号码</font>"; 
} 

?>

使用GD生成文字图片是php一项比较常用的功能,今天介绍生成文字png图片的函数考下。

 
<? 
/* 
php生成文字png图片,可以使用如下方式调用函数: 
http://www.yourdomian.com/text_png.php3?msg=helloworld+class&rot=15&size=48&font=fonts/ARIAL.TTF 
*/ 
Header("Content-type: image/png"); 
class textPNG { 
var $font = 'fonts/TIMES.TTF'; //默认字体. 相对于脚本存放目录的相对路径. 
var $msg = "undefined"; // 默认文字. 
var $size = 24; 
var $rot = 0; // 旋转角度. 
var $pad = 0; // 填充. 
var $transparent = 1; // 文字透明度. 
var $red = 0; // 在黑色背景中... 
var $grn = 0; 
var $blu = 0; 
var $bg_red = 255; // 将文字设置为白色. 
var $bg_grn = 255; 
var $bg_blu = 255; 
function draw() { 
$width = 0; 
$height = 0; 
$offset_x = 0; 
$offset_y = 0; 
$bounds = array(); 
$image = ""; 
// 确定文字高度. 
$bounds = ImageTTFBBox($this->size, $this->rot, $this->font, "W"); 
if ($this->rot < 0) { 
$font_height = abs($bounds[7]-$bounds[1]); 
} else if ($this->rot > 0) { 
$font_height = abs($bounds[1]-$bounds[7]); 
} else { 
$font_height = abs($bounds[7]-$bounds[1]); 
} 
// 确定边框高度. 
$bounds = ImageTTFBBox($this->size, $this->rot, $this->font, $this->msg); 
if ($this->rot < 0) { 
$width = abs($bounds[4]-$bounds[0]); 
$height = abs($bounds[3]-$bounds[7]); 
$offset_y = $font_height; 
$offset_x = 0; 
} else if ($this->rot > 0) { 
$width = abs($bounds[2]-$bounds[6]); 
$height = abs($bounds[1]-$bounds[5]); 
$offset_y = abs($bounds[7]-$bounds[5])+$font_height; 
$offset_x = abs($bounds[0]-$bounds[6]); 
} else { 
$width = abs($bounds[4]-$bounds[6]); 
$height = abs($bounds[7]-$bounds[1]); 
$offset_y = $font_height;; 
$offset_x = 0; 
} 
$image = imagecreate($width+($this->pad*2)+1,$height+($this->pad*2)+1); 
$background = ImageColorAllocate($image, $this->bg_red, $this->bg_grn, $this->bg_blu); 
$foreground = ImageColorAllocate($image, $this->red, $this->grn, $this->blu); 
if ($this->transparent) ImageColorTransparent($image, $background); 
ImageInterlace($image, false); 
// 画图. 
ImageTTFText($image, $this->size, $this->rot, $offset_x+$this->pad, $offset_y+$this->pad, $foreground, $this->font, $this->msg); 
// 输出为png格式. 
imagePNG($image); 
} 
} 
$text = new textPNG; 
if (isset($msg)) $text->msg = $msg; // 需要显示的文字 
if (isset($font)) $text->font = $font; // 字体 
if (isset($size)) $text->size = $size; // 文字大小 
if (isset($rot)) $text->rot = $rot; // 旋转角度 
if (isset($pad)) $text->pad = $pad; // padding 
if (isset($red)) $text->red = $red; // 文字颜色 
if (isset($grn)) $text->grn = $grn; // .. 
if (isset($blu)) $text->blu = $blu; // .. 
if (isset($bg_red)) $text->bg_red = $bg_red; // 背景颜色. 
if (isset($bg_grn)) $text->bg_grn = $bg_grn; // .. 
if (isset($bg_blu)) $text->bg_blu = $bg_blu; // .. 
if (isset($tr)) $text->transparent = $tr; // 透明度 (boolean). 
$text->draw(); 
?> 

 

PHP生成图片验证码、点击切换实例

这篇文章主要介绍了PHP生成图片验证码实例,同时介绍了点击切换(看不清?换一张)效果实现方法,需要的朋友可以参考下

<?php
session_start();
function random($len) {
$srcstr = "1a2s3d4f5g6hj8k9qwertyupzxcvbnm";
mt_srand();
$strs = "";
for ($i = 0; $i < $len; $i++) {
$strs .= $srcstr[mt_rand(0, 30)];
}
return $strs;
}

//随机生成的字符串
$str = random(4);

//验证码图片的宽度
$width  = 50;

//验证码图片的高度
$height = 25;

//声明需要创建的图层的图片格式
@ header("Content-Type:image/png");

//创建一个图层
$im = imagecreate($width, $height);

//背景色
$back = imagecolorallocate($im, 0xFF, 0xFF, 0xFF);

//模糊点颜色
$pix  = imagecolorallocate($im, 187, 230, 247);

//字体色
$font = imagecolorallocate($im, 41, 163, 238);

//绘模糊作用的点
mt_srand();
for ($i = 0; $i < 1000; $i++) {
imagesetpixel($im, mt_rand(0, $width), mt_rand(0, $height), $pix);
}

//输出字符
imagestring($im, 5, 7, 5, $str, $font);

//输出矩形
imagerectangle($im, 0, 0, $width -1, $height -1, $font);

//输出图片
imagepng($im);

imagedestroy($im);

$str = md5($str);

//选择 cookie
//SetCookie("verification", $str, time() + 7200, "/");

//选择 Session
$_SESSION["verification"] = $str;
?>

接下来只要在页面中调用就可以了:

<img id="checkpic" onclick="changing();" src='/images/checkcode.php' />

如果想实现 "看不清?换一张" 效果,添加如下 JS 到页面中

function changing(){
document.getElementById('checkpic').src="/images/checkcode.php?"+Math.random();
}

 

示例一

php 代码

<?php
	try {
		function random($len) {
			$srcstr = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
			mt_srand();
			$strs = "";
			for ($i = 0; $i < $len; $i++) {
				$strs .= $srcstr[mt_rand(0, 62)];
			}
			return $strs;
		}
		$str = random(4);			// 随机生成的字符串
		
		$width  = 50;				// 验证码图片的宽度
		$height = 25;				// 验证码图片的高度
		header("Content-Type:image/png");			// 声明需要创建的图层的图片格式
		
		$im = imagecreate($width, $height);						// 创建一个图层
		$back = imagecolorallocate($im, 0xFF, 0xFF, 0xFF);		// 背景色
		$pix  = imagecolorallocate($im, 187, 230, 247);			// 模糊点颜色
		$font = imagecolorallocate($im, 41, 163, 238);			// 字体色
		
		// 绘模糊作用的点
		mt_srand();
		for ($i = 0; $i < 1000; $i++) {
			imagesetpixel($im, mt_rand(0, $width), mt_rand(0, $height), $pix);
		}

		imagestring($im, 5, 7, 5, $str, $font);						// 输出字符
		imagerectangle($im, 0, 0, $width -1, $height -1, $font);	// 输出矩形(边框)
		imagepng($im);												// 输出图片
		imagedestroy($im);
		
// 		Header ( "Content-type:text/html;charset=utf-8" );
		
		$str = md5($str);
		echo "str: " . $str . "<br><br>";
		
	} catch (Exception $e) {
		echo "+++ error: " . $e . "<br><br>";
	}
?>

运行结果:

php-generating-png-picture-code-11

 

实例二

<?php
	try {
		$p = '1234567890';
		
		if ($p != '') {
			// 生成5位的数字图片
			Header ( "Content-type:image/png" ); // 告诉浏览器,下面的数据是图片,而不要按文字显示
			                                     
			// 定义图片宽高
			$nwidth = 100;
			$nheight = 25;
			$im = imagecreate ( $nwidth, $nheight ) or die ( "Can't initialize new GD image stream" ); // 建立图象
			                                                                                           
			// 图片色彩设置
			$background_color = imagecolorallocate ( $im, 0, 255, 255 ); // 匹配颜色
			$text_color = imagecolorallocate ( $im, 0, 0, 255 );
			
			// 绘制图片边框
			imagerectangle ( $im, -10, 0, $nwidth - 1, $nheight - 1, $background_color ); 		// 绘制矩形
			imagefilledrectangle ( $im, 0, 0, $nwidth - 1, $nheight - 1, $background_color ); 	// 矩形区域着色
			
			srand ( ( double ) microtime () * 1000000 ); // 取得目前时间的百万分之一秒值,以执行时的百万分之一秒当乱数种子
			$randval = rand ();
			$randval = $p;
			imagestring ( $im, 8, 5, 2, $randval, $text_color ); // 绘制横式字串
			                                                      
			// 加入干扰因素
			for($i = 0; $i < 100; $i ++) {
				$randcolor = imagecolorallocate ( $im, rand ( 0, 255 ), rand ( 0, 255 ), rand ( 0, 255 ) );
				imagesetpixel ( $im, rand () % $nwidth, rand () % $nheight, $randcolor ); // 点
			}
			imageinterlace ( $im, 1 );
			imagepng ( $im ); 						// 建立png图型
			imagepng ( $im, 'img/ports/test_1234.png'); 		// 保存png图型到文件
			imagedestroy ( $im ); 					// 结束图型
			
			echo "p : " . $p . "<br><br>";
		} else {
			echo "<font size=2>商家未输入电话号码</font>";
		}
	} catch ( Exception $e ) {
		var_dump ( $e );
	}
?>

运行结果:

php-generating-png-picture-code-12

 

实例三:字符串文字居中

<?php
	function randStr($len=10) {
		$srcstr = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
		mt_srand();
		$strs = "";
		for ($i = 0; $i < $len; $i++) {
			$strs .= $srcstr[mt_rand(0, 62)];
		}
		return $strs;
	}
	
	function gen_image($port='8123') {
		$width = 60;
		$height = 25;
		$fontSize = 8;
		$fontWidth = imagefontwidth ( $fontSize );
		$fontHeight = imagefontheight ( $fontSize );
		$textWidth = $fontWidth * mb_strlen ( $port );
		$x = ceil ( ($width - $textWidth) / 2 );
		$y = ceil ( ($height - $fontHeight) / 2 );
		$img_file = sprintf('img/ports/m_%s.png', randStr());
		
		header("Content-Type:image/png");
		$im = imagecreate ( $width, $height );
		$background_color = imagecolorallocate ( $im, 255, 255, 255 );
		$text_color = imagecolorallocate ( $im, 0, 0, 0 );
		imagerectangle ( $im, 0, 0, $width - 1, $height - 1, $background_color );
		imagestring ( $im, $fontSize, $x, $y, $port, $text_color ); // 绘制横式字串
		imagepng ( $im ); 		// 建立png图型
		imagepng ( $im, $img_file); 		// 建立png图型
		imagedestroy ( $im ); 	// 结束图型
		
		return $img_file;
	}
	
	$port = rand() % 65536;
	gen_image($port);
?>

运行结果:

php-generating-png-picture-code-13

 

实例四

PHP合成图片、生成文字、居中对齐、画线、矩形、三角形、多边形、图片抗锯齿、不失真 高性能源码示例

function generateImg($source, $text1, $text2, $text3, $font = './msyhbd.ttf') {
    $date = '' . date ( 'Ymd' ) . '/';
    $img = $date . md5 ( $source . $text1 . $text2 . $text3 ) . '.jpg';
    if (file_exists ( './' . $img )) {
        return $img;
    }
    
    $main = imagecreatefromjpeg ( $source );
    
    $width = imagesx ( $main );
    $height = imagesy ( $main );
    
    $target = imagecreatetruecolor ( $width, $height );
    
    $white = imagecolorallocate ( $target, 255, 255, 255 );
    imagefill ( $target, 0, 0, $white );
    
    imagecopyresampled ( $target, $main, 0, 0, 0, 0, $width, $height, $width, $height );
    
    $fontSize = 18;//18号字体
    $fontColor = imagecolorallocate ( $target, 255, 0, 0 );//字体的RGB颜色
    
    $fontWidth = imagefontwidth ( $fontSize );
    $fontHeight = imagefontheight ( $fontSize );
    
    $textWidth = $fontWidth * mb_strlen ( $text1 );
    $x = ceil ( ($width - $textWidth) / 2 );//计算文字的水平位置
    
    // $textHeight = $fontHeight;
    // $y = ceil(($height - $textHeight) / 2);//计算文字的垂直位置
    
    imagettftext ( $target, $fontSize, 0, $x, 190, $fontColor, $font, $text1 );
    
    $textWidth = $fontWidth * mb_strlen ( $text2 );
    $x = ceil ( ($width - $textWidth) / 2 );
    
    imagettftext ( $target, $fontSize, 0, $x, 370, $fontColor, $font, $text2 );
    
    $textWidth = $fontWidth * mb_strlen ( $text3 );
    $x = ceil ( ($width - $textWidth) / 2 );
    
    imagettftext ( $target, $fontSize, 0, $x, 560, $fontColor, $font, $text3 );//写文字,且水平居中
    
    //imageantialias($target, true);//抗锯齿,有些PHP版本有问题,谨慎使用
    
    imagefilledpolygon ( $target, array (10 + 0, 0 + 142, 0, 12 + 142, 20 + 0, 12 + 142), 3, $fontColor );//画三角形
    imageline($target, 100, 200, 20, 142, $fontColor);//画线    
    imagefilledrectangle ( $target, 50, 100, 250, 150, $fontColor );//画矩形
    
    //bof of 合成图片
    $child1 = imagecreatefromjpeg ( 'http://gtms01.alicdn.com/tps/i1/T1N0pxFEhaXXXxK1nM-357-88.jpg' );
    imagecopymerge ( $target, $child1, 0, 300, 0, 0, imagesx ( $child1 ), imagesy ( $child1 ), 100 );
    //eof of 合成图片
    
    @mkdir ( './' . $date );
    imagejpeg ( $target, './' . $img, 95 );
    
    imagedestroy ( $main );
    imagedestroy ( $target );
    imagedestroy ( $child1 );
    return $img;
}
//http://my.oschina.net/cart/
generateImg ( 'http://1.popular.sinaapp.com/munv/pic.jpg', '哈哈', '嘿嘿', '呵呵' );
exit ();

 

应用实例

请见米扑博客:  http://proxy.mimvp.com(端口号是图片)

 

总结

1、字体文件需用绝对路径,不推荐相对路径(找不到字体,绘制图会失败)

例如:$ttf_path="../tianshi.ttf" 应该改成 $ttf_path=$_SERVER['DOCUMENT_ROOT'] . "/fonts/tianshi.ttf"

2、imagestring、imagettftext、imagefttext 绘图区别

imagestring:使用默认字体,在图像上绘制简单的字符串

imagettftext:使用指定字体,在图像上绘制使用truetype字体的字符串,使用 TrueType 字体向图像写入文本

imagefttext:使用指定字体,在图像上绘制truetype字体的字符串,使用 FreeType 2 字体将文本写入图像,在PHP 8 可替换 imagettftext,推荐使用 imagefttext

 

bool imagestring ( resource $image , int $font , int $x , int $y , string $string , int $color )

参数说明:

- image: 图像资源。

- font: 字体编号,值可为 1、2、3、4、5。其中1表示5x5的字体,2表示7x7字体,以此类推。

- x: 字符串开始的x坐标。

- y: 字符串开始的y坐标。

- string: 要绘制的字符串,例如:绘制水印"米扑博客,禁止转载"、验证码"Abc12"

- color: 字符串的颜色

 

bool imagettftext ( resource $image , float $size , float $angle , int $x , int $y , int $color , string $fontfile , string $text)

参数说明:

- image: 图像资源。

- size: 字体大小。

- angle: 字符串倾斜角度,默认角度为0,倾斜角度可以 mt_rand(-5,5) 之间的随机数

- x: 字符串开始的x坐标。

- y: 字符串开始的y坐标。

- color: 字符串的颜色。

- fontfile: TrueType字体文件的路径,推荐使用绝对路径,例如:$fontfile=$_SERVER['DOCUMENT_ROOT'] . "/fonts/tianshi.ttf"

- text: 要绘制的字符串,例如:绘制水印"米扑博客,禁止转载"、验证码"Abc12"

 

bool imagefttext ( resource $image , float $size , float $angle , int $x , int $y , int $color , string $fontfile , string $text [, array $extrainfo] )

参数说明:

- image: 图像资源。

- size: 字体大小。

- angle: 字符串倾斜角度。

- x: 字符串开始的x坐标。

- y: 字符串开始的y坐标。

- color: 字符串的颜色。

- fontfile: TrueType字体文件的路径。

- text: 要绘制的字符串。

- extrainfo: 一些额外的绘制参数,比如阴影效果。其取值 $extrainfo = array("linespacing" => 2.0);

注意: 在 PHP 8.0.0 之前,imagefttext() 是 imagettftext() 的扩展变体,它还支持 options。 自 PHP 8.0.0 起,imagettftext() 是 imagefttext() 的别名,推荐使用 imagefttext 

 

 

参考推荐:

ImageMagick 图片处理工具的安装

LNMP(CentOS+Nginx+Mysql+PHP)服务器环境配置