自定义MVC框架之工具类-图像处理类
截止目前已经改造了4个类:
图像处理类:
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框架之工具类-图像处理类的更多相关文章
- 自定义MVC框架之工具类-模型类
截止目前已经改造了5个类: ubuntu:通过封装验证码类库一步步安装php的gd扩展 自定义MVC框架之工具类-分页类的封装 自定义MVC框架之工具类-文件上传类 自定义MVC框架之工具类-图像处理 ...
- 自定义MVC框架之工具类-文件上传类
截止目前已经改造了3个类: ubuntu:通过封装验证码类库一步步安装php的gd扩展 自定义MVC框架之工具类-分页类的封装 该文件上传类功能如下: 1,允许定制上传的文件类型,文件mime信息,文 ...
- 自定义MVC框架之工具类-分页类的封装
以前写过一个MVC框架,封装的有点low,经过一段时间的沉淀,打算重新改造下,之前这篇文章封装过一个验证码类. 这次重新改造MVC有几个很大的收获 >全部代码都是用Ubuntu+Vim编写,以前 ...
- Java Web自定义MVC框架详解 (转)
转自:http://blog.csdn.net/jackfrued/article/details/42774459 最近给学生讲Java Web,希望他们能够在学完这部分内容后自己实现一个MVC框架 ...
- 自定义MVC框架
我们在学习自定义MVC框架的时候常常会听到Model1 ,Model2和MVC.那么什么是Model1 什么是Model2什么又是MVC呢? 什么是Model1? Model1就是一种纯jsp开发技术 ...
- Struts2 自定义MVC框架
一.Model1与Model2: Model1:就是一种纯jsp开发技术,将业务逻辑代码和视图渲染代码杂糅在一起. Model2:Model2是在Model1的基础上,将业务逻辑的代码分离开来,单独形 ...
- 第一章 自定义MVC框架
第一章 自定义MVC框架1.1 MVC模式设计 组成:Model:模型,用于数据和业务的处理 View :视图,用于数据的显示 Controller:控制器 ...
- c#自定义ORM框架---(泛型&反射&实体类扩展属性<附带通用增、删、查、改>)
该教材主要是运用到泛型.反射和实体类扩展属性 步骤一.建立扩展属性类 实体类扩展属性要继承Attribute基类完成 [AttributeUsage(AttributeTargets.Property ...
- 使用Intellij Idea自定义MVC框架
---恢复内容开始--- 今天我学习了自定义一个简单的MVC框架,这个我们首先要知道什么是MVC框架! MVC框架: MVC全名是Model View Controller,是模型(model)-视图 ...
随机推荐
- Linux系统文件压缩与备份(5)
在 Linux 系统选有相当多的压缩命令可以使用,这些压缩指令可以让我们更方便的从网上下载大型文件,本章第一节内容我们就来谈谈这个 Linux 系统下常用的几种压缩格式吧. 谈完了压缩后,我们接着来说 ...
- PHP 获取两个时间之间的月份
## 获取两个时间之间的间距时间 $s = '2017-02-05'; $e = '2017-07-20'; $start = new \DateTime($s); $end = new \DateT ...
- 分布式锁实现思路及开源项目集成到springmvc并使用
分布式锁顾名思义就是在分布式系统下的锁,而使用锁的唯一目的就是为了防止多个请求同时对某一个资源进行竞争性读写 在使用多线程时,为了让某一资源某一时刻只能有一个操作者,经常使用synchronized, ...
- lnmp平台搭设
软件链接:https://pan.baidu.com/s/14gAZ67iXWhEdzvEXMiGfVg 提取码:ai1s 只是在一台服务器上搭设,为centos7.2环境 安 ...
- VSTO:C#获取文档控件的值
基础知识准备: VSTO入门 创建Excel解决方案 string[] inputfileNames = { @"C:\1.xls", @"C:\2.xls" ...
- python------virtualenv&virtualenvwrapper的使用
virtualenv virtualenv 的作用:为单个项目创建独立的python虚拟环境 virtualenv的使用 : 1.通过如下命令安装virtualenv $ sudo pip insta ...
- Cookies与session的区别
Cookies 机制 Cookies是服务器在本地机器上存储的一段文本,并随每一个请求发送至同一个服务器. IETF RFC2965 HTTP State Management Mechanism 是 ...
- (转)Python: super 没那么简单
原文:https://mozillazg.com/2016/12/python-super-is-not-as-simple-as-you-thought.html python 约定¶ 单继承¶ 多 ...
- Anaconda 科学计算环境与包的管理
相信大多数 python 的初学者们都曾为开发环境问题折腾了很久,包管理和 python 不同版本的问题,特别是 window 环境安装个 scrapy 各种报错 ,使用 Anaconda 可以很好的 ...
- 源码分析篇 - Android绘制流程(三)requestLayout()与invalidate()流程及Choroegrapher类分析
本文主要探讨能够触发performTraversals()执行的invalidate().postInvalidate()和requestLayout()方法的流程.在调用这三个方法到最后执行到per ...