截止目前已经改造了4个类:

ubuntu:通过封装验证码类库一步步安装php的gd扩展

自定义MVC框架之工具类-分页类的封装

自定义MVC框架之工具类-文件上传类

图像处理类:

1,图片加水印处理( 支持任意位置与九宫格位置 )

2,图片缩放处理( 等比缩放,不变形裁剪 )

 <?php

 class Image{
//文件路径
protected $path;
//是否允许随机文件名称
protected $enableRandName;
//文件类型
protected $type;
//错误号
protected $errorNo;
//错误信息
protected $errorInfo; public function __construct( $_path = './', $_enableRandName = true ){
$this->path = $_path;
$this->enableRandName = $_enableRandName;
} public function __get( $key ) {
if( $key == 'errorNo' ) {
return $this->errorNo;
}else if( $key == 'errorInfo' ) {
return $this->getErrorInfo();
}
}
protected function getErrorInfo(){
$info = '';
switch( $this->errorNo ){
case 1000:
$info = "水印或者图片源文件不存在";
break;
case 1001:
$info = '水印图片的尺寸(宽或者高)大于图片本身';
break;
}
return $info;
} //获取图片信息
public static function getImageInfo( $imgPath ){
$data = getimagesize( $imgPath );
$info['width'] = $data[0];
$info['height'] = $data[1];
$info['mime'] = $data['mime'];
return $info;
} /*
* @srcImg 原图片
* @waterImg 水印图片
* @pos 水印位置
* @alpha 透明度
* @prefix 水印处理之后的图片前缀
* */
public function waterMark( $srcImg, $waterImg, $pos, $alpha, $prefix = 'ghostwu_' ){
//检查图片和水印是否存在
if( !file_exists( $srcImg )
|| !file_exists( $waterImg ) ) {
$this->errorNo = 1000;
return false;
} //获取图片和水印信息
$srcImageInfo = self::getImageInfo( $srcImg );
$waterImageInfo = self::getImageInfo( $waterImg ); $this->type = explode( '/', $srcImageInfo['mime'] )[1]; //检查水印和图片的尺寸, 水印是否能加在图片上
if( !$this->check( $srcImageInfo, $waterImageInfo ) ) {
$this->errorNo = 1001;
return false;
} //打开图片文件和水印文件资源
$imgRes = self::openImage( $srcImg );
$waterRes = self::openImage( $waterImg ); //计算水印图片位置
$waterPos = $this->calcPosition( $pos, $srcImageInfo, $waterImageInfo ); //合成水印图片
imagecopymerge ( $imgRes, $waterRes, $waterPos['x'], $waterPos['y'], 0, 0, $waterImageInfo['width'], $waterImageInfo['height'], $alpha ); //得到文件的保存名字
$saveName = $this->getFileName( $srcImg, $prefix ); //拼凑完整的文件名称
$fullPath = rtrim( $this->path, '/' ) . '/' . $saveName; //保存添加水印后的文件
$this->saveImage( $imgRes, $fullPath ); imagedestroy( $imgRes );
imagedestroy( $waterRes ); return $fullPath;
} protected function saveImage( $imgRes, $fullPath ){
$func = 'image' . $this->type;
$func( $imgRes, $fullPath );
} protected function getFileName( $imgPath, $prefix ){
if ( $this->enableRandName ) {
$saveName = $prefix . uniqid() . '.' . $this->type;
}else {
$saveName = $prefix . pathinfo( $imgPath )['filename'] . '.' . $this->type;
}
return $saveName;
} protected function calcPosition( $pos, $imageInfo, $waterImageInfo ){
$x = 0; $y = 0;
switch( $pos ) {
case 1: //左上角
$x = 0; $y = 0;
break;
case 2: //上中
$x = ( $imageInfo['width'] - $waterImageInfo['width'] ) / 2;
$y = 0;
break;
case 3: //右上角
$x = $imageInfo['width'] - $waterImageInfo['width'];
$y = 0;
break;
case 4: //左边中间
$x = 0;
$y = ( $imageInfo['height'] - $waterImageInfo['height'] ) / 2;
break;
case 5: //正中间
$x = ( $imageInfo['width'] - $waterImageInfo['width'] ) / 2;
$y = ( $imageInfo['height'] - $waterImageInfo['height'] ) / 2;
break;
case 6: //右边中间
$x = $imageInfo['width'] - $waterImageInfo['width'];
$y = ( $imageInfo['height'] - $waterImageInfo['height'] ) / 2;
break;
case 7: //左下角
$x = 0;
$y = $imageInfo['height'] - $waterImageInfo['height'];
break;
case 8: //中间下面
$x = ( $imageInfo['width'] - $waterImageInfo['width'] ) / 2;
$y = $imageInfo['height'] - $waterInfo['height'];
break;
case 9: //右下角
$x = $imageInfo['width'] - $waterImageInfo['width'];
$y = $imageInfo['height'] - $waterImageInfo['height'];
break;
case 0: //随机位置
$x = mt_rand( 0, $imageInfo['width'] - $waterImageInfo['width'] );
$y = mt_rand( 0, $imageInfo['height'] - $waterImageInfo['height'] );
break;
}
return [ 'x' => $x, 'y' => $y ];
} public static function openImage( $imagePath ){
$mime = self::getImageInfo( $imagePath )['mime'];
switch( $mime ){
case 'image/gif':
$im = imagecreatefromgif( $imagePath );
break;
case 'image/jpeg':
$im = imagecreatefromjpeg( $imagePath );
break;
case 'image/png':
$im = imagecreatefrompng( $imagePath );
break;
case 'image/wbmp':
$im = imagecreatefromwbmp( $imagePath );
break;
}
return $im;
} public function check( $imgInfo, $waterInfo ){
if( $imgInfo['width'] < $waterInfo['width']
|| $imgInfo['height'] < $waterInfo['height'] ){
return false;
}
return true;
} /*
* @srcImg 原图片路径
* @dstImg 目标图片路径
* @newWidth 缩放后新的图片宽度
* @newHeight 缩放后新的图片高度
* */
public function thumb( $srcImg, $newWidth, $newHeight, $prefix="thumb_" ){
$srcIm = self::openImage( $srcImg );
$srcInfo = self::getImageInfo( $srcImg );
$srcW = $srcInfo['width'];
$srcH = $srcInfo['height'];
$this->type = explode( '/', $srcInfo['mime'] )[1];
$ratio_w = $newWidth / $srcW;
$ratio_h = $newHeight / $srcH;
$ratio = 1.0; //缩放后的图片 宽度/高度 都比原图大或者小
if( ( $ratio_w < 1 && $ratio_h < 1 ) || ( $ratio_w > 1 && $ratio_h > 1 ) ) {
if( $ratio_w < $ratio_h ) {
$ratio = $ratio_h;
}else {
$ratio = $ratio_w;
}
$tmp_w = (int)( $newWidth / $ratio );
$tmp_h = (int)( $newHeight / $ratio );
$tmp_im = imagecreatetruecolor( $tmp_w, $tmp_h );
//生成一个以原图片最大边长,比例为ratio的中间图像
imagecopy( $tmp_im, $srcIm, 0, 0, 0, 0, $tmp_w, $tmp_h );
//定义一个目标尺寸的图像
$newIm = imagecreatetruecolor( $newWidth, $newHeight );
imagecopyresampled( $newIm, $tmp_im, 0, 0, 0, 0, $newWidth, $newHeight, $tmp_w, $tmp_h );
}else {
//缩放后的图片 宽度/高度 一个比原图大, 另一个比原图小
$ratio = $ratio_h > $ratio_w ? $ratio_h : $ratio_w; //取比例大的那个值 $tmp_w=(int)($srcW * $ratio);
$tmp_h=(int)($srcH * $ratio);
$tmp_im = imagecreatetruecolor($tmp_w, $tmp_h); imagecopyresampled($tmp_im, $srcIm, 0, 0, 0, 0, $tmp_w, $tmp_h, $srcW, $srcH ); $newIm = imagecreatetruecolor($newWidth, $newHeight);
imagecopy($newIm, $tmp_im, 0, 0, 0, 0, $newWidth, $newHeight);
}
//处理后的文件的保存名字
$saveName = $this->getFileName( $newIm, $prefix ); //拼凑完整的文件名称
$fullPath = rtrim( $this->path, '/' ) . '/' . $saveName; $this->saveImage( $newIm, $fullPath ); imagedestroy( $newIm ); return $fullPath;
}
} $img = new Image();
//$img->waterMark( '1.jpg', 'logo.png', 5, 30 );
echo $img->thumb( '1.jpg', 330, 495 ); ?>

自定义MVC框架之工具类-图像处理类的更多相关文章

  1. 自定义MVC框架之工具类-模型类

    截止目前已经改造了5个类: ubuntu:通过封装验证码类库一步步安装php的gd扩展 自定义MVC框架之工具类-分页类的封装 自定义MVC框架之工具类-文件上传类 自定义MVC框架之工具类-图像处理 ...

  2. 自定义MVC框架之工具类-文件上传类

    截止目前已经改造了3个类: ubuntu:通过封装验证码类库一步步安装php的gd扩展 自定义MVC框架之工具类-分页类的封装 该文件上传类功能如下: 1,允许定制上传的文件类型,文件mime信息,文 ...

  3. 自定义MVC框架之工具类-分页类的封装

    以前写过一个MVC框架,封装的有点low,经过一段时间的沉淀,打算重新改造下,之前这篇文章封装过一个验证码类. 这次重新改造MVC有几个很大的收获 >全部代码都是用Ubuntu+Vim编写,以前 ...

  4. Java Web自定义MVC框架详解 (转)

    转自:http://blog.csdn.net/jackfrued/article/details/42774459 最近给学生讲Java Web,希望他们能够在学完这部分内容后自己实现一个MVC框架 ...

  5. 自定义MVC框架

    我们在学习自定义MVC框架的时候常常会听到Model1 ,Model2和MVC.那么什么是Model1 什么是Model2什么又是MVC呢? 什么是Model1? Model1就是一种纯jsp开发技术 ...

  6. Struts2 自定义MVC框架

    一.Model1与Model2: Model1:就是一种纯jsp开发技术,将业务逻辑代码和视图渲染代码杂糅在一起. Model2:Model2是在Model1的基础上,将业务逻辑的代码分离开来,单独形 ...

  7. 第一章 自定义MVC框架

    第一章  自定义MVC框架1.1 MVC模式设计    组成:Model:模型,用于数据和业务的处理          View :视图,用于数据的显示          Controller:控制器 ...

  8. c#自定义ORM框架---(泛型&反射&实体类扩展属性<附带通用增、删、查、改>)

    该教材主要是运用到泛型.反射和实体类扩展属性 步骤一.建立扩展属性类 实体类扩展属性要继承Attribute基类完成 [AttributeUsage(AttributeTargets.Property ...

  9. 使用Intellij Idea自定义MVC框架

    ---恢复内容开始--- 今天我学习了自定义一个简单的MVC框架,这个我们首先要知道什么是MVC框架! MVC框架: MVC全名是Model View Controller,是模型(model)-视图 ...

随机推荐

  1. Windows安装python3.x后,pip list警告!DEPRECATION: The default format will switch to columns in the future.

    前言(凑字数专用) 这个警告虽然不影响你的正常使用,但是每次都好几行红色警告,总是给人一种怪怪的感觉(当然不是FBI的警告了……),所以咱们还是把他解决掉~ 网上好多解决办法都是Ubuntu的解决办法 ...

  2. Swift 里 Array (二)初始化

    init() 函数 在 Array 里 public init() { _buffer = _Buffer() } 以Buffer 是 _ContiguousArrayBuffer 为例. 即初始化了 ...

  3. cmd命令关闭占用程序的端口

    遇到的问题: 在重新启动tomcat服务时,启动失败,显示的信息大概为:Error running 'cus_manager_system': Unable to open debugger port ...

  4. python的datetime常用方法

    把datetime转成字符串 datetime.strftime("%Y-%m-%d-%H") 把字符串转成datetime datetime.strptime(datetime, ...

  5. javascript数据结构与算法---检索算法(二分查找法、计算重复次数)

    javascript数据结构与算法---检索算法(二分查找法.计算重复次数) /*只需要查找元素是否存在数组,可以先将数组排序,再使用二分查找法*/ function qSort(arr){ if ( ...

  6. python使用(二)

    Python中的集合类型. 1.list_option.py 2.listsplit_option.py 3. dic_option.py 4.iter_option.py 1.list_option ...

  7. IdentityServer4 Hybrid 模式

    原文参考:Switching to Hybrid Flow and adding API Access back 接上篇:IdentityServer-Protecting an API using ...

  8. 多线程编程——ANR

    1.为什么要用多线程 这里列出几个原因: 提高用户体验或者避免ANR:在事件处理代码中需要使用多线程,否则会出现ANR(Application is not responding),或者因为响应较慢导 ...

  9. Activity四大启动模式

    ctivity的四种启动模式: standard.singleTop.singleTask.singleInstance 为了打印方便,定义一个基础Activity,在其onCreate方法和onNe ...

  10. 前端通信:ajax设计方案(五)--- 集成promise规范,更优雅的书写代码(改迭代已作废,移步迭代10)

    该迭代已作废,最新的请移步这里:https://www.cnblogs.com/GerryOfZhong/p/10726306.html 距离上一篇博客书写,又过去了大概几个月了,这段时间暂时离开了这 ...