php 图片处理类

<?php
/**
* 图片类
* @author <420012223@qq.cn>
*/
class Image {
public $uploadImagePath = './tmp';//上传图片地址
public $cropImagePath = './tmp';//切图图片地址
public $fileExt;//允许的文件格式
public $fileSize;//字节,默认2M
public function __construct()
{
$this->fileExt = array('.jpg','.png','.jpeg','.gif');
$this->fileSize = 2*1024*1024;
}
/**
* 扩展信息
*/
private function expand($file){
list($width,$height) = getimagesize($file);
$res['width'] = $width;
$res['height'] = $height;
return $res;
}
/**
* [文件名]
* @param [type] $filename [description]
* @return [type] [description]
*/
private function fileName($filename=null){
if($filename){return $filename;}
$mics = explode(' ', microtime());
return $mics[1].str_replace('0.', '', $mics[0]);
}
/**
* [上传的文件路径]
* @param [type] $filepath [description]
* @param boolean $isdata [description]
* @return [type] [description]
*/
private function filePath($filepath=null,$isdata=true){
$filepath .= $isdata ? '/'.date('Y').'/'.date('m').'/'.date('d').'/' : null;
return $filepath;
}
/**
* [源文件地址]
* @param [type] $filepath [description]
* @param boolean $isdata [description]
* @return [type] [description]
*/
private function imageFilePath($filepath){
if($imagePath = strstr($filepath, '/tmp')){
$filepath = '.'.$imagePath;
}
return $filepath;
}
/**
* [显示的图片路径]
* @return [type] [description]
*/
private function imagePath($filePath){
return 'http://'.$_SERVER['SERVER_NAME'].substr($filePath,1);
}
/**
* [文件后缀]
* @param [type] $file [description]
* @return [type] [description]
*/
private function fileExt($file){
return strtolower(strrchr($file,'.'));
}
/**
* [普通上传-本地服务器]
* @param array $params [description]
* fileName //[选填] 要生成图片名,默认时间戳
* fileKey //[选填] file控件名,默认Filedata
* fileExt //[选填]允许的图片格式,默认array('.jpg','.png','.jpeg')
* @return [type] [description]
* error 0 成功 1 错误
* msg 描述
* filePath 文件路径
* width 宽
* height 高
*/
function upload($params=array()){
$res['error'] = 1;
$fileKey = $params["fileKey"] ? $params["fileKey"] : 'Filedata';
$fileSize = $_FILES[$fileKey]['size'];//文件大小
if($fileSize > $this->fileSize){
$res['msg'] = '文件过大!';
return $res;
}
$tempFile = $_FILES[$fileKey]['tmp_name'];//临时文件
$uploadFileName = $_FILES[$fileKey]['name'];//上传的文件名
$fileExt = empty($params['fileExt']) ? $this->fileExt : $params['fileExt'];//允许的文件格式
$fileExtStr = $this->fileExt($uploadFileName); //文件.jpg 后缀
if(!in_array($fileExtStr, $fileExt)){
$res['msg'] = '文件不合法!';
return $res;
}
//文件路径
$filePath = $this->filePath($this->uploadImagePath);
//尝试创建目标文件夹,如果它不存在,
if(!is_dir($filePath)) {
if(!mkdir($filePath,0777,true)){
$res['msg'] = "The destination directory could not be created.";
return $res;
}
}
//文件名称
$fileName = $this->fileName($params['fileName']).$fileExtStr;
$filePath .= $fileName;
$res = $this->expand($tempFile);
if(move_uploaded_file($tempFile,$filePath)){
$res['error'] = 0;
$res['filePath'] = $this->imagePath($filePath);
$res['msg'] = '上传成功';
}else{
$res['msg'] = '上传失败';
}
$res['fileName'] = $uploadFileName;
return $res; }
/**
* [缩图]
* @param array $params [description]
* file [必填]源图片
* height [必填]要生成图片的高
* width [必填]要生成图片的宽
* scale [选填]按比例缩图,默认true
* bgcolor [选填]背景颜色,(white,black,gray),默认原图
* @return [type] [description]
*/
function thumb($params=array()){
$res['error'] = 1;
$createImagePath = $this->filePath($this->cropImagePath); //存放图片路径
$sourceImage = $this->imageFilePath($params['file']);//源图片
$width = intval($params['width']);//宽
$height = intval($params['height']);//高
$bgcolor = $params['bgcolor'];
$src_x = 0; //设定载入图片要载入的区域x坐标
$src_y = 0; //设定载入图片要载入的区域y坐标
$dst_x = 0; //设定需要载入的图片在新图中的x坐标
$dst_y = 0; //设定需要载入的图片在新图中的y坐标
$scale = $params['scale'] == 'false' ? false : true;//按比例
if(!$width || !$height){
$res['msg'] = 'Some of the required parameters are missing.';
return $res;
}
//验证GD库
if(! extension_loaded('gd')){
$res['msg'] = "The GD extension is not installed on the server.";
return $res;
} //确保源文件存在
if(!file_exists($sourceImage)) {
$res['msg'] = "The source image file could not be found.";
return $res;
} //尝试创建目标文件夹,如果它不存在,
if(!is_dir($createImagePath)) {
if(!mkdir($createImagePath,0777,true)){
$res['msg'] = "The destination directory could not be created.";
return $res;
}
} //确保目标文件夹是可写的
if(!is_writable($createImagePath)){
$res['msg'] = "The server does not have permission to write in the destination folder.";
return $res;
} //要创建的文件名和后缀
$extension = $this->fileExt($sourceImage);
$fileExt = empty($params['fileExt']) ? $this->fileExt : $params['fileExt'];//允许的文件格式
if(!in_array($extension, $fileExt)){
$res['msg'] = '文件不合法!';
return $res;
} $thumb = $this->fileName() . $extension; //要创建的文件和路径
$target_file = $createImagePath . $thumb;
//源图片信息
$info = getimagesize($sourceImage);
$sourceImageWidth = $info[0];
$sourceImageheight = $info[1];
if(!$info){
$res['msg'] = "The file type is not supported.";
return $res;
} //我们使用GD库加载图像,使用文件扩展名来选择合适的功能
// 返回一图像标识符,代表了从给定的文件名取得的图像
switch($info[2]) {
case IMAGETYPE_GIF:
if(!$source_image = imagecreatefromgif($sourceImage)){
$res['msg'] = "Could not open GIF file.";
return $res;
}
break;
case IMAGETYPE_PNG:
if(!$source_image = imagecreatefrompng($sourceImage)){
$res['msg'] = "Could not open PNG file.";
return $res;
}
break;
case IMAGETYPE_JPEG:
if(!$source_image = imagecreatefromjpeg($sourceImage)){
$res['msg'] = "Could not open JPG file.";
return $res;
}
break;
default:
$res['msg'] = "The file type is not supported.";
return $res;
break;
} if($scale == false){//比例
$dest_width = $width;
$dest_height = $height;
}else{
//计算基于所选择的区域和最小值的新的大小
if($sourceImageWidth > $sourceImageheight) {//宽大于高
$dest_width = $width;
$dest_height = round($sourceImageheight*$width/$sourceImageWidth);
$dst_y = $bgcolor ? round(($height-$dest_height)/2) : $dst_y;
} else {//高大于宽
$dest_width = round($sourceImageWidth*$height/$sourceImageheight);
$dest_height = $height;
$dst_x = $bgcolor ? round(($width-$dest_width)/2) : $dst_x;
}
}
if($bgcolor){//背景颜色
//$dest_image = imagecreate($width,$height);
$dest_image = imagecreatetruecolor($width,$height);
if($bgcolor == 'black'){//黑
$imgbgcolor = imagecolorallocate($dest_image, 0, 0, 0);
}elseif($bgcolor == "gray"){//灰
$imgbgcolor = imagecolorallocate($dest_image, 200, 200, 200);
}else{//白
$imgbgcolor = imagecolorallocate($dest_image, 255, 255, 255);
}
imagefill($dest_image, 0, 0, $imgbgcolor);//填充颜色
}else{
//我们产生上述计算的大小的新图像对象
if(!$dest_image = imagecreatetruecolor($dest_width, $dest_height)){
$res['msg'] = "Could not create new image from source file.";
return $res;
}
//保持透明GIF和PNG
if($info[2]==IMAGETYPE_GIF||$info[2]==IMAGETYPE_PNG){
if($info[2]==IMAGETYPE_PNG){
imageAntiAlias($dest_image,true);//对线段和多边形启用快速画图抗锯齿方法
}
//imagecolorallocatealpha的行为和 imagecolorallocate() 相同,但多了一个额外的透明度参数 alpha,其值从 0 到 127。0 表示完全不透明,127 表示完全透明。
$color = imagecolorallocatealpha($dest_image, 0, 0, 0,127);
//将 image 图像中的透明色设定为 color
imagecolortransparent($dest_image, $color);
imagealphablending($dest_image, false);// 允许在真彩色图像上使用两种不同的绘画模式
imagesavealpha($dest_image, true);//设置标记以在保存 PNG 图像时保存完整的 alpha 通道信息(与单一透明色相反)
}
}
//拷贝图像
if(!imagecopyresampled($dest_image, $source_image, $dst_x, $dst_y, $src_x, $src_y, $dest_width, $dest_height, $sourceImageWidth, $sourceImageheight)){
$res['msg'] = "Could not crop the image with the provided coordinates.";
return $res;
} //生成图片
$quality = 80;//范围从 0(最差质量,文件更小)到 100(最佳质量,文件最大)。默认为 IJG 默认的质量值(大约 75)。
switch($info[2]) {
case IMAGETYPE_GIF:
if(!imagegif($dest_image, $target_file)){
$res['msg'] = "Could not save GIF file.";
return $res;
}
break;
case IMAGETYPE_PNG:
if(!imagepng($dest_image, $target_file, max(9 - floor($quality/10),0))){
$res['msg'] = "Could not save PNG file.";
return $res;
}
break;
case IMAGETYPE_JPEG:
if(!imagejpeg($dest_image, $target_file, $quality)){
$res['msg'] = "Could not save JPG file.";
return $res;
}
break;
}
//释放与 image 关联的内存
imagedestroy($dest_image);
imagedestroy($source_image);
$res['error'] = 0;
$res['filePath'] = $this->imagePath($target_file);
$res['msg'] = "success";
$res['width'] = $dest_width;
$res['height'] = $dest_height;
$res['fileName'] = $params['fileName'];
return $res;
}
/**
* [切图]
* @param array $params [description]
* file [必填]源图片
* height [必填]要生成图片的高
* width [必填]要生成图片的宽
* top [选填]top偏移,默认0
* left [选填]left偏移,默认0
* maxWidth [选填]最大宽度,默认width值
* maxHeight [选填]最大高度,默认height值
* @return [type] [description]
*/
function crop($params=array()){
$res['error'] = 1;
$createImagePath = $this->filePath($this->cropImagePath); //存放图片路径
$sourceImage = $this->imageFilePath($params['file']);//源图片
$top = isset($params['top']) ? intval($params['top']) : 0;//top 偏移
$left = isset($params['left']) ? intval($params['left']) : 0;//left 偏移
$width = intval($params['width']);//宽
$height = intval($params['height']);//高
$maxWidth = isset($params['maxWidth']) ? intval($params['maxWidth']) : $width;//最大宽
$maxHeight = isset($params['maxHeight']) ? intval($params['maxHeight']) : $height;//最大高 if(!$width || !$height){
$res['msg'] = 'Some of the required parameters are missing.';
return $res;
}
//验证GD库
if(! extension_loaded('gd')){
$res['msg'] = "The GD extension is not installed on the server.";
return $res;
} //确保源文件存在
if(!file_exists($sourceImage)) {
$res['msg'] = "The source image file could not be found.";
return $res;
} //尝试创建目标文件夹,如果它不存在,
if(!is_dir($createImagePath)) {
if(!mkdir($createImagePath,0777,true)){
$res['msg'] = "The destination directory could not be created.";
return $res;
}
} //确保目标文件夹是可写的
if(!is_writable($createImagePath)){
$res['msg'] = "The server does not have permission to write in the destination folder.";
return $res;
} //要创建的文件名和后缀
$extension = $this->fileExt($sourceImage);
$fileExt = empty($params['fileExt']) ? $this->fileExt : $params['fileExt'];//允许的文件格式
if(!in_array($extension, $fileExt)){
$res['msg'] = '文件不合法!';
return $res;
} $thumb = $this->fileName() . $extension; //要创建的文件和路径
$target_file = $createImagePath . $thumb;
//源图片信息
$info = getimagesize($sourceImage);
if(!$info){
$res['msg'] = "The file type is not supported.";
return $res;
} //我们使用GD库加载图像,使用文件扩展名来选择合适的功能
// 返回一图像标识符,代表了从给定的文件名取得的图像
switch($info[2]) {
case IMAGETYPE_GIF:
if(!$source_image = imagecreatefromgif($sourceImage)){
$res['msg'] = "Could not open GIF file.";
return $res;
}
break;
case IMAGETYPE_PNG:
if(!$source_image = imagecreatefrompng($sourceImage)){
$res['msg'] = "Could not open PNG file.";
return $res;
}
break;
case IMAGETYPE_JPEG:
if(!$source_image = imagecreatefromjpeg($sourceImage)){
$res['msg'] = "Could not open JPG file.";
return $res;
}
break;
default:
$res['msg'] = "The file type is not supported.";
return $res;
break;
} //计算基于所选择的区域和最小值的新的大小
if($width > $height) {
$dest_width = $maxWidth;
$dest_height = round($maxWidth*$height/$width);
} else {
$dest_width = round($maxHeight*$width/$height);
$dest_height = $maxHeight;
} //我们产生上述计算的大小的新图像对象
if(!$dest_image = imagecreatetruecolor($dest_width, $dest_height)){
$res['msg'] = "Could not create new image from source file.";
return $res;
} //保持透明GIF和PNG
if($info[2]==IMAGETYPE_GIF||$info[2]==IMAGETYPE_PNG){
if($info[2]==IMAGETYPE_PNG){
//imageAntiAlias($dest_image,true);//对线段和多边形启用快速画图抗锯齿方法
}
//imagecolorallocatealpha的行为和 imagecolorallocate() 相同,但多了一个额外的透明度参数 alpha,其值从 0 到 127。0 表示完全不透明,127 表示完全透明。
$color = imagecolorallocatealpha($dest_image, 0, 0, 0,127);
//将 image 图像中的透明色设定为 color
imagecolortransparent($dest_image, $color);
imagealphablending($dest_image, false);// 允许在真彩色图像上使用两种不同的绘画模式
imagesavealpha($dest_image, true);//设置标记以在保存 PNG 图像时保存完整的 alpha 通道信息(与单一透明色相反)
} //拷贝图像
if(!imagecopyresampled($dest_image, $source_image, 0, 0, $left, $top, $dest_width, $dest_height, max($width, $maxWidth), max($height, $maxHeight))){
$res['msg'] = "Could not crop the image with the provided coordinates.";
return $res;
} //生成图片
$quality = 80;//范围从 0(最差质量,文件更小)到 100(最佳质量,文件最大)。默认为 IJG 默认的质量值(大约 75)。
switch($info[2]) {
case IMAGETYPE_GIF:
if(!imagegif($dest_image, $target_file)){
$res['msg'] = "Could not save GIF file.";
return $res;
}
break;
case IMAGETYPE_PNG:
if(!imagepng($dest_image, $target_file, max(9 - floor($quality/10),0))){
$res['msg'] = "Could not save PNG file.";
return $res;
}
break;
case IMAGETYPE_JPEG:
if(!imagejpeg($dest_image, $target_file, $quality)){
$res['msg'] = "Could not save JPG file.";
return $res;
}
break;
}
//释放与 image 关联的内存
imagedestroy($dest_image);
imagedestroy($source_image);
$res['error'] = 0;
$res['filePath'] = $this->imagePath($target_file);
$res['msg'] = "success";
$res['width'] = $dest_width;
$res['height'] = $dest_height;
$res['fileName'] = $params['fileName'];
return $res;
}
/**
* [又拍云-上传]
* @param array $params [description]
* $params['file'] //[选填]图片文件,默认$_FILES[$fileKey]['tmp_name']
* $params['fileExt'] //[选填]允许的图片格式,默认array('.jpg','.png','.jpeg')
* $params['fileName'] //[选填]图片名称,带后缀,默认时间戳
* fileKey //[选填] file控件名,默认Filedata
* $params['fileKey'] //[选填] file控件名,默认Filedata
* @return [array] [description]
* $res['error'] //0成功1错误
* $res['msg'] //描述
* $res['filePath'] //新的文件路径
*/
function ypyUpload($params=array()){
$res = null;
$res['error'] = 1;
$fileKey = $params["fileKey"] ? $params["fileKey"] : 'Filedata';
require_once(APPPATH.'third_party/upyun.class.php');
try {
if($params['file']){//图片文件
$tempFile = $this->imageFilePath($params['file']);
$uploadFileName = $params['fileName'] ? $params['fileName'] : $tempFile;
$fileSize = filesize($tempFile);
}else{
$tempFile = $_FILES[$fileKey]['tmp_name'];
$uploadFileName = $_FILES[$fileKey]['name'];
$fileSize = $_FILES[$fileKey]['size'];//文件大小
} if($fileSize > $this->fileSize){
$res['msg'] = '文件过大!';
return $res;
}
$fileExt = empty($params['fileExt']) ? $this->fileExt : $params['fileExt'];
$fileExtStr = $this->fileExt($uploadFileName); //.jpg 后缀
if(!in_array($fileExtStr, $fileExt)){
$res['msg'] = '文件不合法!';
return $res;
}
$res = $this->expand($tempFile);
$upyun = new UpYun('Bucketname', 'Username', 'Userpass');
$fh = fopen($tempFile, 'rb');
//文件名称
$fileName = $this->fileName($params['fileName']).$fileExtStr;
$filePath = $this->filePath().$fileName;
$rsp = $upyun->writeFile($filePath, $fh, True); // 上传图片,自动创建目录
fclose($fh);
if($rsp){
$res['error'] = 0;
$res['msg'] = "上传成功";
$res['filePath'] = "http://getarts.b0.upaiyun.com".$filePath;
}else{
$res['msg'] = "上传失败";
} }catch(Exception $e) {
$res['msg'] = $e->getCode().'-'.$e->getMessage();
}
$res['fileName'] = $uploadFileName;
return $res;
}
/**
* [又拍云删除文件接口]
* $file
* string http://getarts.b0.upaiyun.com//demo/sample_thumb_2.jpeg
* array(
* 'http://getarts.b0.upaiyun.com//demo/sample_thumb_2.jpeg',
* 'http://getarts.b0.upaiyun.com//demo/sample_thumb_2.jpeg',
* )
* @return [type] [description]
* error 1错误,0成功
* msg 描述
* errorFiles array('demo/sample_thumb_2.jpeg'=>'描述')
*/
function ypyDeleteFile($file){
$res['error'] = 1;
if(is_array($file)){
foreach ($file as $key => $val) {
$flag = $this->_ypyDeleteFile($val);
if($flag != "true"){
$res['errorFiles'][$val] = $flag;
}
}
if($res['errorFiles']){
$res['msg'] = 'errorFiles';
}else{
$res['error'] = 0;
$res['msg'] = 'success';
}
}else{
$flag = $this->_ypyDeleteFile($file);
if($flag == 'true'){
$res['error'] = 0;
$res['msg'] = 'success';
}else{
$res['error'] = 1;
$res['msg'] = $flag;
}
}
return $res;
}
/**
* [又拍云删除文件]
* @param [string] $file [description]
* @return [string] [description]
*/
private function _ypyDeleteFile($file){
require_once(APPPATH.'third_party/upyun.class.php');
$file = str_replace('http://getarts.b0.upaiyun.com', '', $file);
try {
$upyun = new UpYun('Bucketname', 'Username', 'Userpass');
$res = $upyun->deleteFile($file);
if($res == true || $res == 'NULL' || is_null($res)){
$res = 'true';
}
}catch(Exception $e) {
$res = $e->getCode().'-'.$e->getMessage();
}
return $res;
}
/**
* [图片rgb分析]
* @param [type] $params [description]
* $params['file'] //[必填]图片文件
* $params['height'] //[选填]生成分析图片的高,默认3
* $params['width'] //[选填]生成分析图片的宽,默认3
* @return [array] [description]
* $res['rgb'] array array(123,1324,1234)
* $res['rgb16'] string FAF123
*/
public function imageRgb($params){
if (!$params['file']) {return false;}
$thumbPara['file'] = $params['filePath'];
$thumbPara['height'] = intval($params['height']) ? $params['height'] : 3;
$thumbPara['width'] = intval($params['width']) ? $params['width'] : 3;
$thumbInfo = $this->thumb($thumbPara);
$imageFile = $thumbInfo['filePath'];
$imageInfo = getimagesize($imageFile);
$width = $imageInfo[0];
$height = $imageInfo[1];
if(!$width || !$height) {return false;}
switch($imageInfo[2]) {
case 1:
$handleImage = imagecreatefromgif($imageFile);
break;
case 2:
$handleImage = imagecreatefromjpeg($imageFile);
break;
case 3:
$handleImage = imagecreatefrompng($imageFile);
break;
}
$res = array();
for ($x=1; $x<=$width; $x++) {
for ($y=1; $y<=$height; $y++) {
$rgb = imagecolorat($handleImage, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
$rgb16 = $this->rgb10Torgb16($r, $g, $b);
$res[$rgb16] = array('rgb'=>array($r,$g,$b),'rgb16'=>$rgb16);
}
}
return $res;
}
/**
* [颜色rgb转hsl]
*/
public function rgbToHsl($r, $g, $b){
$r /= 255;
$g /= 255;
$b /= 255;
$max = max($r, $g, $b);
$min = min($r, $g, $b);
$h = $s = $l = ($max + $min) / 2;
if($max == $min){
$h = $s = 0;
}else{
$d = $max - $min;
$s = $l > 0.5 ? $d / (2 - $max - $min) : $d / ($max + $min);
switch($max){
case $r: $h = ($g - $b) / $d + ($g < $b ? 6 : 0); break;
case $g: $h = ($b - $r) / $d + 2; break;
case $b: $h = ($r - $g) / $d + 4; break;
}
$h /= 6;
}
return array($h, $s, $l);
}
/**
* [hsl 转 rgb 规则]
*/
private function hue2rgb($p, $q, $t){
if($t < 0) {
$t += 1;
}elseif($t > 1) {
$t -= 1;
} if($t < 1/6){
$p = $p + ($q - $p) * 6 * $t;
}elseif($t < 1/2){
$p = $q;
}elseif($t < 2/3){
$p = $p + ($q - $p) * (2/3 - $t) * 6;
}
return round($p*255);
}
/**
* [颜色hsl转rgb]
*/
public function hslToRgb($h, $s, $l){
if($s == 0){
$r = $g = $b = $l;
}else{
$q = $l < 0.5 ? $l * (1 + $s) : $l + $s - $l * $s;
$p = 2 * $l - $q;
$r = $this->hue2rgb($p, $q, $h + 1/3);
$g = $this->hue2rgb($p, $q, $h);
$b = $this->hue2rgb($p, $q, $h - 1/3);
}
return array($r, $g, $b);
}
/**
* [hsl反色规则]
*/
public function setHsl($h, $s, $l){
if ($s>0.5 && $l>0.5) {
$res['title'] = array($h, $s-0.5, 0.8);
$res['text'] = array($h, $s-0.5, 0.7);
$res['link'] = array($h, $s-0.5, $l-0.5);
} elseif($s>0.5 && $l<=0.5) {
$res['title'] = array($h, $s-0.5, 1);
$res['text'] = array($h, $s-0.5, 0.8);
$res['link'] = array($h, $s-0.5, $l+0.5);
} elseif($s<=0.5 && $l>0.5) {
$res['title'] = array($h, $s+0.5, 0.1);
$res['text'] = array($h, $s+0.5, 0.2);
$res['link'] = array($h, $s+0.5, $l-0.5);
} elseif($s<=0.5 && $l<0.5) {
$res['title'] = array($h, $s+0.5, 1);
$res['text'] = array($h, $s+0.5, $l+0.5);
$res['link'] = array($h, $s+0.5, $l+0.5);
}
return $res;
}
/**
* [rgb10转rgb16]
*/
public function rgb10Torgb16($r, $g, $b){
$rgb16 = strtoupper( $r>15 ? dechex($r) : '0'.dechex($r));
$rgb16 .= strtoupper( $g>15 ? dechex($g) : '0'.dechex($g));
$rgb16 .= strtoupper( $b>15 ? dechex($b) : '0'.dechex($b));
return $rgb16;
}
}
?>
上一篇:2019.01.21 NOIP训练 ak树(点分治)


下一篇:如何在Centos7下升级Apache至最新版本