php 縮圖生成類別,支援imagemagick及gd庫兩種處理
功能:
1.按比例縮小/放大
2.填充背景色
3.按區域裁剪
4.添加水印,包括水印的位置,透明度等
實現,
imagemagick位址:www.imagemagick.org需要安裝imagemagick,安裝方法如下:點擊查看
<?php
/** 缩略图生成类,支持imagemagick及gd库两种处理
* Date: 2013-07-15
* Author: fdipzone
* Ver: 1.2
*
* Func:
* public set_config: 设置参数
* public create_thumb: 生成缩略图
* private fit: 缩略图片
* private crop: 裁剪图片
* private gd_fit: GD库缩略图片
* private gd_crop: GD库裁剪图片
* private get_size: 获取要转换的size
* private get_crop_offset: 获取裁图的偏移量
* private add_watermark: 添加水印
* private check_handler: 判断处理程序是否已安装
* private create_dirs: 创建目录
* private exists: 判断参数是否存在
* private to_log: 记录log
* private hex2rgb: hex颜色转rgb颜色
* private get_file_ext: 获取图片类型
*
* ver: 1.1 增加GD库处理
* ver: 1.2 增加width,height错误参数处理
* 增加当图片colorspace不为RGB时作转RGB处理
* 修正使用crop保存为gif时出现透明无效区域问题,使用+repage参数,删除透明无效区域即可
*
* tips:建议使用imagemagick
* GD库不支持透明度水印,如果必须使用透明水印,请将水印图片做成有透明度。
* GD库输出gif如加透明水印,会有问题。
*/
class PicThumb{ // class start
private $_log = null; // log file
private $_handler = null; // 进行图片处理的程序,imagemagick/gd库
private $_type = 'fit'; // fit or crop
private $_source = null; // 原图路径
private $_dest = null; // 缩略图路径
private $_watermark = null; // 水印图片
private $_opacity = 75; // 水印圖片透明度,gd库不支持
private $_gravity = 'SouthEast'; // 水印摆放位置 NorthWest, North, NorthEast, West, Center, East, SouthWest, South, SouthEast
private $_geometry = '+10+10'; // 水印定位,gd库不支持
private $_croppos = 'TL'; // 截图的位置 TL TM TR ML MM MR BL BM BR
private $_bgcolor = null; // 填充的背景色
private $_quality = 90; // 生成的图片质量
private $_width = null; // 指定区域宽度
private $_height = null; // 指定区域高度
// 初始化
public function __construct($logfile=''){
if($logfile!=''){
$this->_log = $logfile;
}
}
// 设置参数
public function set_config($param=array()){
$this->_handler = $this->exists($param, 'handler')? strtolower($param['handler']) : null;
$this->_type = $this->exists($param, 'type')? strtolower($param['type']) : 'fit';
$this->_watermark = $this->exists($param, 'watermark')? $param['watermark'] : null;
$this->_opacity = $this->exists($param, 'opacity')? $param['opacity'] : 75;
$this->_gravity = $this->exists($param, 'gravity')? $param['gravity'] : 'SouthEast';
$this->_geometry = $this->exists($param, 'geometry')? $param['geometry'] : '+10+10';
$this->_croppos = $this->exists($param, 'croppos')? $param['croppos'] : 'TL';
$this->_bgcolor = $this->exists($param, 'bgcolor')? $param['bgcolor'] : null;
$this->_quality = $this->exists($param, 'quality')? $param['quality'] : 90;
$this->_width = $this->exists($param, 'width')? $param['width'] : null;
$this->_height = $this->exists($param, 'height')? $param['height'] : null;
}
/** 创建缩略图
* @param String $source 原图
* @param String $dest 目标图
* @return boolean
*/
public function create_thumb($source, $dest){
// 检查使用的handler是否已安装
if(!$this->check_handler()){
$this->to_log('handler not installed');
return false;
}
// 判断区域宽高是否正确
if(!is_numeric($this->_width) || !is_numeric($this->_height) || $this->_width<=0 || $this->_height<=0){
$this->to_log('width or height invalid');
return false;
}
// 判断源文件是否存在
if(!file_exists($source)){
$this->to_log($source.' not exists');
return false;
}
// 创建目标文件路径
if(!$this->create_dirs($dest)){
$this->to_log(dirname($dest).' create fail');
return false;
}
$this->_source = $source; // 源文件
$this->_dest = $dest; // 目标文件
// 处理图片
switch($this->_type){
case 'fit':
if($this->_handler=='imagemagick'){
return $this->fit();
}else{
return $this->gd_fit();
}
break;
case 'crop':
if($this->_handler=='imagemagick'){
return $this->crop();
}else{
return $this->gd_crop();
}
break;
default:
$this->to_log($this->_type.' not fit and crop');
return false;
}
}
/** 按比例压缩或拉伸图片
* @return boolean
*/
private function fit(){
// 判断是否填充背景
$bgcolor = ($this->_bgcolor!=null)?
sprintf(" -background '%s' -gravity center -extent '%sx%s' ", $this->_bgcolor, $this->_width, $this->_height) : "";
// 判断是否要转为RGB
$source_info = getimagesize($this->_source);
$colorspace = (!isset($source_info['channels']) || $source_info['channels']!=3)? ' -colorspace RGB ' : '';
// 命令行
$cmd = sprintf("convert -resize '%sx%s' '%s' %s -quality %s %s '%s'", $this->_width, $this->_height, $this->_source, $bgcolor,
$this->_quality, $colorspace, $this->_dest);
// 记录执行的命令
$this->to_log($cmd);
// 执行命令
exec($cmd);
// 添加水印
$this->add_watermark($this->_dest);
return is_file($this->_dest)? true : false;
}
/** 裁剪图片
* @return boolean
*/
private function crop(){
// 获取生成的图片尺寸
list($pic_w, $pic_h) = $this->get_size();
// 获取截图的偏移量
list($offset_w, $offset_h) = $this->get_crop_offset($pic_w, $pic_h);
// 判断是否要转为RGB
$source_info = getimagesize($this->_source);
$colorspace = (!isset($source_info['channels']) || $source_info['channels']!=3)? ' -colorspace RGB ' : '';
// 命令行
$cmd = sprintf("convert -resize '%sx%s' '%s' -quality %s %s -crop %sx%s+%s+%s +repage '%s'", $pic_w, $pic_h, $this->_source,
$this->_quality, $colorspace, $this->_width, $this->_height, $offset_w, $offset_h, $this->_dest);
// 记录执行的命令
$this->to_log($cmd);
// 执行命令
exec($cmd);
// 添加水印
$this->add_watermark($this->_dest);
return is_file($this->_dest)? true : false;
}
/** GD库按比例压缩或拉伸图片
* @return boolean
*/
private function gd_fit(){
// 获取生成的图片尺寸
list($pic_w, $pic_h) = $this->get_size();
list($owidth, $oheight, $otype) = getimagesize($this->_source);
switch($otype){
case 1: $source_img = imagecreatefromgif($this->_source); break;
case 2: $source_img = imagecreatefromjpeg($this->_source); break;
case 3: $source_img = imagecreatefrompng($this->_source); break;
default: return false;
}
// 按比例缩略/拉伸图片
$new_img = imagecreatetruecolor($pic_w, $pic_h);
imagecopyresampled($new_img, $source_img, 0, 0, 0, 0, $pic_w, $pic_h, $owidth, $oheight);
// 判断是否填充背景
if($this->_bgcolor!=null){
$bg_img = imagecreatetruecolor($this->_width, $this->_height);
$rgb = $this->hex2rgb($this->_bgcolor);
$bgcolor =imagecolorallocate($bg_img, $rgb['r'], $rgb['g'], $rgb['b']);
imagefill($bg_img, 0, 0, $bgcolor);
imagecopy($bg_img, $new_img, (int)(($this->_width-$pic_w)/2), (int)(($this->_height-$pic_h)/2), 0, 0, $pic_w, $pic_h);
$new_img = $bg_img;
}
// 获取目标图片的类型
$dest_ext = $this->get_file_ext($this->_dest);
// 生成图片
switch($dest_ext){
case 1: imagegif($new_img, $this->_dest, $this->_quality); break;
case 2: imagejpeg($new_img, $this->_dest, $this->_quality); break;
case 3: imagepng($new_img, $this->_dest, (int)(($this->_quality-1)/10)); break;
}
if(isset($source_img)){
imagedestroy($source_img);
}
if(isset($new_img)){
imagedestroy($new_img);
}
// 添加水印
$this->add_watermark($this->_dest);
return is_file($this->_dest)? true : false;
}
/** GD库裁剪图片
* @return boolean
*/
private function gd_crop(){
// 获取生成的图片尺寸
list($pic_w, $pic_h) = $this->get_size();
// 获取截图的偏移量
list($offset_w, $offset_h) = $this->get_crop_offset($pic_w, $pic_h);
list($owidth, $oheight, $otype) = getimagesize($this->_source);
switch($otype){
case 1: $source_img = imagecreatefromgif($this->_source); break;
case 2: $source_img = imagecreatefromjpeg($this->_source); break;
case 3: $source_img = imagecreatefrompng($this->_source); break;
default: return false;
}
// 按比例缩略/拉伸图片
$tmp_img = imagecreatetruecolor($pic_w, $pic_h);
imagecopyresampled($tmp_img, $source_img, 0, 0, 0, 0, $pic_w, $pic_h, $owidth, $oheight);
// 裁剪图片
$new_img = imagecreatetruecolor($this->_width, $this->_height);
imagecopyresampled($new_img, $tmp_img, 0, 0, $offset_w, $offset_h, $this->_width, $this->_height, $this->_width, $this->_height);
// 获取目标图片的类型
$dest_ext = $this->get_file_ext($this->_dest);
// 生成图片
switch($dest_ext){
case 1: imagegif($new_img, $this->_dest, $this->_quality); break;
case 2: imagejpeg($new_img, $this->_dest, $this->_quality); break;
case 3: imagepng($new_img, $this->_dest, (int)(($this->_quality-1)/10)); break;
}
if(isset($source_img)){
imagedestroy($source_img);
}
if(isset($tmp_img)){
imagedestroy($tmp_img);
}
if(isset($new_img)){
imagedestroy($new_img);
}
// 添加水印
$this->add_watermark($this->_dest);
return is_file($this->_dest)? true : false;
}
/** 获取目标图生成的size
* @return Array $width, $height
*/
private function get_size(){
list($owidth, $oheight) = getimagesize($this->_source);
$width = (int)($this->_width);
$height = (int)($this->_height);
switch($this->_type){
case 'fit':
$pic_w = $width;
$pic_h = (int)($pic_w*$oheight/$owidth);
if($pic_h>$height){
$pic_h = $height;
$pic_w = (int)($pic_h*$owidth/$oheight);
}
break;
case 'crop':
$pic_w = $width;
$pic_h = (int)($pic_w*$oheight/$owidth);
if($pic_h<$height){
$pic_h = $height;
$pic_w = (int)($pic_h*$owidth/$oheight);
}
break;
}
return array($pic_w, $pic_h);
}
/** 获取截图的偏移量
* @param int $pic_w 图宽度
* @param int $pic_h 图高度
* @return Array $offset_w, $offset_h
*/
private function get_crop_offset($pic_w, $pic_h){
$offset_w = 0;
$offset_h = 0;
switch(strtoupper($this->_croppos)){
case 'TL':
$offset_w = 0;
$offset_h = 0;
break;
case 'TM':
$offset_w = (int)(($pic_w-$this->_width)/2);
$offset_h = 0;
break;
case 'TR':
$offset_w = (int)($pic_w-$this->_width);
$offset_h = 0;
break;
case 'ML':
$offset_w = 0;
$offset_h = (int)(($pic_h-$this->_height)/2);
break;
case 'MM':
$offset_w = (int)(($pic_w-$this->_width)/2);
$offset_h = (int)(($pic_h-$this->_height)/2);
break;
case 'MR':
$offset_w = (int)($pic_w-$this->_width);
$offset_h = (int)(($pic_h-$this->_height)/2);
break;
case 'BL':
$offset_w = 0;
$offset_h = (int)($pic_h-$this->_height);
break;
case 'BM':
$offset_w = (int)(($pic_w-$this->_width)/2);
$offset_h = (int)($pic_h-$this->_height);
break;
case 'BR':
$offset_w = (int)($pic_w-$this->_width);
$offset_h = (int)($pic_h-$this->_height);
break;
}
return array($offset_w, $offset_h);
}
/** 添加水印
* @param String $dest 图片路径
*/
private function add_watermark($dest){
if($this->_watermark!=null && file_exists($this->_watermark) && file_exists($dest)){
list($owidth, $oheight, $otype) = getimagesize($dest);
list($w, $h, $wtype) = getimagesize($this->_watermark);
// 水印图比原图要小才加水印
if($w<=$owidth && $h<=$oheight){
if($this->_handler=='imagemagick'){ // imagemagick 添加水印
$cmd = sprintf("composite -gravity %s -geometry %s -dissolve %s '%s' %s %s", $this->_gravity, $this->_geometry,
$this->_opacity, $this->_watermark, $dest, $dest);
$this->to_log($cmd);
exec($cmd);
}else{ // gd 添加水印
switch($wtype){
case 1: $water_img = imagecreatefromgif($this->_watermark); break;
case 2: $water_img = imagecreatefromjpeg($this->_watermark); break;
case 3: $water_img = imagecreatefrompng($this->_watermark); break;
default: return false;
}
switch($otype){
case 1: $dest_img = imagecreatefromgif($dest); break;
case 2: $dest_img = imagecreatefromjpeg($dest); break;
case 3: $dest_img = imagecreatefrompng($dest); break;
default: return false;
}
// 水印位置
switch(strtolower($this->_gravity)){
case 'northwest':
$posX = 0;
$posY = 0;
break;
case 'north':
$posX = ($owidth - $w) / 2;
$posY = 0;
break;
case 'northeast':
$posX = $owidth - $w;
$posY = 0;
break;
case 'west':
$posX = 0;
$posY = ($oheight - $h) / 2;
break;
case 'center':
$posX = ($owidth - $w) / 2;
$posY = ($oheight - $h) / 2;
break;
case 'east':
$posX = $owidth - $w;
$posY = ($oheight - $h) / 2;
break;
case 'southwest':
$posX = 0;
$posY = $oheight - $h;
break;
case 'south':
$posX = ($owidth - $w) / 2;
$posY = $oheight - $h;
break;
case 'southeast':
$posX = $owidth - $w;
$posY = $oheight - $h;
break;
}
imagealphablending($dest_img, true);
imagecopy($dest_img, $water_img, $posX, $posY, 0, 0, $w, $h);
switch($otype){
case 1:imagegif($dest_img, $dest, $this->_quality); break;
case 2:imagejpeg($dest_img, $dest, $this->_quality); break;
case 3:imagepng($dest_img, $dest, (int)(($this->_quality-1)/10)); break;
}
if(isset($water_img)){
imagedestroy($water_img);
}
if(isset($dest_img)){
imagedestroy($dest_img);
}
}
}
}
}
/** 判断处理程序是否已安装
* @return boolean
*/
private function check_handler(){
$handler = $this->_handler;
if(!in_array($handler, array('imagemagick', 'gd', null))){
return false;
}
// 检查是否有安装imagemagick
$imagemagick_installed = strstr(shell_exec('convert -version'),'Version: ImageMagick')!=''? true : false;
// 检查是否有安装gd库
$gd_installed = function_exists('gd_info')? true : false;
switch($handler){
case 'imagemagick':
return $imagemagick_installed;
break;
case 'gd':
return $gd_installed;
break;
case null:
if($imagemagick_installed){
$this->_handler = 'imagemagick';
return true;
}
if($gd_installed){
$this->_handler = 'gd';
return true;
}
break;
}
return false;
}
/** 创建图片目录
* @param String $path
* @return boolean
*/
private function create_dirs($dest){
if(!is_dir(dirname($dest))){
return mkdir(dirname($dest), 0777, true);
}
return true;
}
/** 判断参数是否存在
* @param Array $obj 数组对象
* @param String $key 要查找的key
* @return boolean
*/
private function exists($obj,$key=''){
if($key==''){
return isset($obj) && !empty($obj);
}else{
$keys = explode('.',$key);
for($i=0,$max=count($keys); $i<$max; $i++){
if(isset($obj[$keys[$i]])){
$obj = $obj[$keys[$i]];
}else{
return false;
}
}
return isset($obj) && !empty($obj);
}
}
/** 记录log
* @param String $msg 要记录的log讯息
*/
private function to_log($msg){
if($this->_log){
$msg = '['.date('Y-m-d H:i:s').']'.$msg."\r\n";
file_put_contents($this->_log, $msg, FILE_APPEND);
}
}
/** hex颜色转rgb颜色
* @param String $color hex颜色
* @return Array
*/
private function hex2rgb($hexcolor){
$color = str_replace('#', '', $hexcolor);
if (strlen($color) > 3) {
$rgb = array(
'r' => hexdec(substr($color, 0, 2)),
'g' => hexdec(substr($color, 2, 2)),
'b' => hexdec(substr($color, 4, 2))
);
} else {
$r = substr($color, 0, 1) . substr($color, 0, 1);
$g = substr($color, 1, 1) . substr($color, 1, 1);
$b = substr($color, 2, 1) . substr($color, 2, 1);
$rgb = array(
'r' => hexdec($r),
'g' => hexdec($g),
'b' => hexdec($b)
);
}
return $rgb;
}
/** 获取图片类型
* @param String $file 图片路径
* @return int
*/
private function get_file_ext($file){
$filename = basename($file);
list($name, $ext)= explode('.', $filename);
$ext_type = 0;
switch(strtolower($ext)){
case 'jpg':
case 'jpeg':
$ext_type = 2;
break;
case 'gif':
$ext_type = 1;
break;
case 'png':
$ext_type = 3;
break;
}
return $ext_type;
}
} // class end
?>
以上就是php 縮圖生成類,支援imagemagick及gd庫兩種處理的內容,更多相關內容請關注PHPcn(www.php.cn)!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

PHP 8.4 帶來了多項新功能、安全性改進和效能改進,同時棄用和刪除了大量功能。 本指南介紹如何在 Ubuntu、Debian 或其衍生版本上安裝 PHP 8.4 或升級到 PHP 8.4

Visual Studio Code,也稱為 VS Code,是一個免費的原始碼編輯器 - 或整合開發環境 (IDE) - 可用於所有主要作業系統。 VS Code 擁有大量針對多種程式語言的擴展,可以輕鬆編寫

本教程演示瞭如何使用PHP有效地處理XML文檔。 XML(可擴展的標記語言)是一種用於人類可讀性和機器解析的多功能文本標記語言。它通常用於數據存儲

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

字符串是由字符組成的序列,包括字母、數字和符號。本教程將學習如何使用不同的方法在PHP中計算給定字符串中元音的數量。英語中的元音是a、e、i、o、u,它們可以是大寫或小寫。 什麼是元音? 元音是代表特定語音的字母字符。英語中共有五個元音,包括大寫和小寫: a, e, i, o, u 示例 1 輸入:字符串 = "Tutorialspoint" 輸出:6 解釋 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。總共有 6 個元

靜態綁定(static::)在PHP中實現晚期靜態綁定(LSB),允許在靜態上下文中引用調用類而非定義類。 1)解析過程在運行時進行,2)在繼承關係中向上查找調用類,3)可能帶來性能開銷。

PHP的魔法方法有哪些? PHP的魔法方法包括:1.\_\_construct,用於初始化對象;2.\_\_destruct,用於清理資源;3.\_\_call,處理不存在的方法調用;4.\_\_get,實現動態屬性訪問;5.\_\_set,實現動態屬性設置。這些方法在特定情況下自動調用,提升代碼的靈活性和效率。
