首页

列表页

详情页

php裁剪教程交流世界上最好的编程说话PHP图层裁剪办事搭建详解 Docker

以上的需求,每天都在发生,虽然可以通过CSS来掌握显示大小。
但是如果图片过大,会造成加载的延迟,影响网站整体性能。
因此,我们须要一个做事器来帮助我们进行图片的裁剪
传统做法是,上传原图像,然后根据提前方案好的尺寸进行图片的裁剪,然后保存各种尺寸的缩略图,每种尺寸的缩略图都在磁盘上有一个文件及文件名,下次访问时通过图片名称访问不同的缩略图,当有新的尺寸需求时,修正代码,多天生一个尺寸的缩略图,如下类似的代码,假设利用一个函数来天生缩略图:

cutImg(100,100); //裁剪为100100的缩略图 cutImg(100,200); //裁剪为100200的缩略图 / 这时添加一个新需求,500500 像素的缩略图 / cutImg(500,500); //这里添加一条代码天生一个新需求

这种办法不足优雅,于是我们想想,有没有办法采取另一种办法,比如,我只上传一张图片,在利用时,通过需求可以显示任务尺寸的缩略图,而且不用预先方案,如:

这是一张原图:

图片地址:http://qiniu.imecho.cn/apic15589.png

1、裁剪 100 100

如果这时根据UI的布局需求,须要一张:100px 100px 的图片

这时我发送一个要求:http://qiniu.imecho.cn/apic15589.png?imageView2/1/w/100/h/100

2、裁剪 200 50

如果有一个页面还是显示同一张图片,但这时哀求图片大小是: 200px 50px 的图片

这时我们发送一个要求:http://qiniu.imecho.cn/apic15589.png?imageView2/1/w/200/h/50

发送要求:http://qiniu.imecho.cn/apic15589.png?imageView2/0/w/200/h/50

3、圆角图片

如果,其余一个页面,我须要一个圆角图片 ? 。


难道只能利用CSS吗?当然不是,请看下面:

发送要求:http://qiniu.imecho.cn/apic15589.png?roundPic/radius/30

4、加水印

如果,我要加一个水印呢:传统方法,得在代码里添加: 添加水印的代码,比如:

addWater('原图路径','水印图路径',$top,$left); //$top 距原图上边的间隔,$left 距原图左边的间隔

而且水印是固定的,一但天生水印,须要修正水印,须要重修改代码,同时,再次实行代码,那能不能通过要求来来动态天生水印呢?肯定是可以的,如:

要求:http://qiniu.imecho.cn/apic15589.png?watermark/1/image/aHR0cHM6Ly93d3cuYmFpZHUuY29tL2ltZy9iZF9sb2dvMS5wbmc=/dissolve/100/dx/50/dy/200

5、压缩图片

如果图片文件太大,网络传输韶光太长,想要压缩:如下:

压缩前

压缩后

还有更多的需求,比如图片旋转,图片调色,图片格式转换等,是否可以通过这种动态天生图片的办法实现呢,而且完备不用修正原代码,直接通过要求参数实现

接下来,剖析下PHP如何才能实现以上功能

总体架构

1、 后台上传图片,到文件做事器【不做任务处理】

2、 浏览器发送要求

3、 做事器解析要求,并选择指定的处理接口【压缩、裁剪、圆角、加水印,其它】

4、 根据要求加载原图片,并根据选择的接口天生终极图片

5、 返回给浏览器

实现步骤1、 环境先容

基于PHPstudy集成开拓环境

域名:

项目目录: E:\project\php\image

开启 rewrite 重定向,优化URL

项目目录构造:

2、图片上传

利用百度的 Web Uploader 上传图片即可,详细实现可以参考官网:

http://fex.baidu.com/webuploader/

图片上传不是本文剖析的重点, 文件上传功能已经实现

前端页面:

后端可以利用百度供应的,也可以自己实现。

3、 Rewrite 重定向

下图的案例可以看到,我们访问图片是能过网址加图片名称的办法

它是通过 Apache的重定向实现的,\"大众.htaccess\"大众 这个文件便是配置文件,代码如下

<IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.)$ img.php </IfModule>4、 入口文件实现

所有的图片访问都是通过 \公众img.php\公众 文件来实现的,那么它是如何事情的..

<?php require_once \"大众function.php\公众; require_once \"大众init.php\"大众;

\"大众function.php\"大众 文件

<?php function json($code=0,$msg=''){ $arr = ['code'=>$code, 'msg'=>$msg]; exit(json_encode($arr,JSON_UNESCAPED_UNICODE)); }

\公众init.php\"大众文件

<?php define('ROOT_PATH', dirname(__FILE__)); //系统根目录 define('DS',DIRECTORY_SEPARATOR); //目录分隔符 define('IMAGE_PATH',ROOT_PATH . DS . 'img' . DS); //图片路径 define('PLUGIN_PATH',ROOT_PATH . DS . 'plugin' .DS); //插件路径 define('IMAGE_CACHE_PATH',ROOT_PATH . DS . 'img_cache' . DS); //处理过的图片缓存路径 ​ include_once PLUGIN_PATH . 'plugin.php'; //加载插件 ​ //get要求参数 $query_string = isset($_SERVER['QUERY_STRING'])?$_SERVER['QUERY_STRING']:''; ​ //图片处理,以插件的形式处理图片,每个插件都是对 $im 进行处理 if($query_string != ''){ include_once \"大众route.php\"大众; }else{ //输出图片,不做任何处理 $plugin = new plugin(); header('Content-type:'.$plugin->mime); //输出类型 echo file_get_contents($plugin->img_file); exit; }5、 路由的实现

这里的路由很大略,无非便是通过要求?号后面的第一个参数,然后根据参数名引入对应的插件文件,然后实现化插件,代码:

<?php //取得插件名称 $plugin_name = $query_string; if(strpos($query_string,'/') !== false){ $plugin_name = substr($query_string,0,strpos($query_string,'/')); } //加载插件 $plugin_file = PLUGIN_PATH . $plugin_name . '.php'; //插件文件 if(!file_exists($plugin_file)){ json(4,'参数禁绝确'); }else{ include_once $plugin_file; new $plugin_name($query_string); //实例化插件 }6、压缩图片

压缩图片是通过 imageslim 这个插件来实现的, 文件名 \"大众plugin/imageslim.php\"大众

代码:

<?php class imageslim extends plugin{ public function __construct(){ parent::__construct(); ​ $create_fun = $this->create_fun; //打开图片函数名 $out_fun = $this->out_fun; //输出图片函数名 ​ $im = $create_fun($this->img_file); //创建图片工具 if(!$im){ json(3,'打开图像失落败'); } ​ header('Content-type:'.$this->mime); //输出类型 $out_fun($im,null,50); //输出图片 imagedestroy($im); //销毁图片 } }

可以看到,实现事理很大略, imageslim 继续 plugin 插件,

plugin.php 插件实现一此成员变量的定义,及一些初始化操作

比如,文件名、文件类型、文件大小,代码如下:

<?php class plugin { public $img_name; public $img_file; public $img_mime; public $mime; public $extension; public $create_fun; public $out_fun; public $src_w; //原始图片的宽 public $src_h; //原始图片的高 ​ public function __construct() { //文件检讨 $this->img_name = trim($_SERVER['REDIRECT_URL'],'/'); $this->img_file = IMAGE_PATH . $this->img_name; if(!file_exists($this->img_file)){ json(1,'文件不存在'); } //图片类型检讨 $this->img_mime = ['image/gif','image/png','image/jpeg','image/bmp','image/webp','image/x-icon','image/tiff']; //图片mime $this->mime = mime_content_type($this->img_file); // 返回 mime 类型 if(!in_array($this->mime,$this->img_mime)){ json(2,'不是一张有效图片'); } ​ $this->extension = pathinfo($this->img_file,PATHINFO_EXTENSION); //获取图片后缀 $mime_end = substr($this->mime,6); $this->create_fun = 'imagecreatefrom'.$mime_end; //打开图片函数名 $this->out_fun = 'image'.$mime_end; //输出图片函数名 ​ //原始图片尺寸 $image_info = getimagesize($this->img_file); $this->src_w = $image_info[0]; $this->src_h = $image_info[1]; } }

只有两个关键函数,

第一个函数: Imgecreatefromjpeg 或 imagcreatefrompng 紧张是根据图片的类型是什么来调用对应的打开函数

第二个函数: imagejpeg 或 imagepng 也是根据图片类型来输出对应的函数

7、裁剪图片

这里是才是裁剪图片紧张的功能,我们须要根据各种需求进行裁剪,事情中我们都会若何进行裁剪呢?

第一种: 等比缩放到我们指定的宽,或指定的高

要求接口:http://www.image.com/26.jpg?imageview/0/w/300/h/200

限定缩略图的长边最多为<LongEdge>,短边最多为<ShortEdge>,进行等比缩放,不裁剪。

如果只指定 w 参数则表示限定长边(短边自适应),只指定 h 参数则表示限定短边(长边自适应)

关键函数: imagecopyresized

第二种:等比缩放,居中裁剪

要求接口:http://www.image.com/26.jpg?imageView/1/w/100/h/140

限定缩略图的宽最少为<Width>,高最少为<Height>,进行等比缩放,居中裁剪。

转后的缩略图常日恰好是 <Width>x<Height> 的大小(有一个边缩放的时候会由于超出矩形框而被裁剪掉多余部分)。

如果只指定 w 参数或只指定 h 参数,代表限定为长宽相等的正方图

第三种:等比缩放,不裁剪

要求接口http://www.image.com/26.jpg?imageView/2/w/100/h/140

限定缩略图的宽最多为<Width>,高最多为<Height>,进行等比缩放,不裁剪。
如果只指定 w 参数则表示限定宽(长自适应),

只指定 h 参数则表示限定长(宽自适应)。
它和模式0类似,差异只是限定宽和高,不是限定长边和短边。

从运用处景来说,模式0适宜移动设备上做缩略图,模式2适宜PC上做缩略图

第四种:限定宽高最小值,不裁剪

要求接口http://www.image.com/26.jpg?imageView/3/w/100/h/140

限定缩略图的宽最少为<Width>,高最少为<Height>,进行等比缩放,不裁剪。
如果只指定 w 参数或只指定 h 参数,代表长脱期制为同样的值。
你可以理解为模式1是模式3的结果再做居中裁剪得到的

总结

以上便是基本的图片裁剪,当然还有一些裁剪模式,我们没有实现 ,比如固定大小,等比缩放,并居中显示,如下

再者还有,添加水印等功能,都属于图片裁剪,由于篇幅有限,其它功能自行研究逐一实现

IT技能研习社,专注互联网技能研究与分享,喜好的朋友可以点击【关注】;把履历通报给有梦想的人;