您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > php

PHP图层裁剪服务搭建详解

时间:2019-07-31 17:50:30  来源:  作者:



概述

每一个做过WEB程序开发的程序员(比如,博客、电商),应该都有这样的体验,有时候我们需要在不同的页面显示不同尺寸的图片,比如,首页、商品列表页、详情页,如下:

首页

世界上最好的编程语言PHP图层裁剪服务搭建详解

 

列表页

世界上最好的编程语言PHP图层裁剪服务搭建详解

 

详情页

世界上最好的编程语言PHP图层裁剪服务搭建详解

 

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

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

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

这是一张原图:

图片地址:http://qiniu.imecho.cn/apic15589.png
世界上最好的编程语言PHP图层裁剪服务搭建详解

 

1、裁剪 100 * 100

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

这时我发送一个请求:http://qiniu.imecho.cn/apic15589.png?imageView2/1/w/100/h/100
世界上最好的编程语言PHP图层裁剪服务搭建详解

 

2、裁剪 200 * 50

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

这时我们发送一个请求:http://qiniu.imecho.cn/apic15589.png?imageView2/1/w/200/h/50
世界上最好的编程语言PHP图层裁剪服务搭建详解

 

发送请求:http://qiniu.imecho.cn/apic15589.png?imageView2/0/w/200/h/50
世界上最好的编程语言PHP图层裁剪服务搭建详解

 

3、圆角图片

如果,另外一个页面,我需要一个圆角图片 ? 。。。难道只能使用CSS吗?当然不是,请看下面:

发送请求:http://qiniu.imecho.cn/apic15589.png?roundPic/radius/30
世界上最好的编程语言PHP图层裁剪服务搭建详解

 

4、加水印

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

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

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

请求:http://qiniu.imecho.cn/apic15589.png?watermark/1/image/aHR0cHM6Ly93d3cuYmFpZHUuY29tL2ltZy9iZF9sb2dvMS5wbmc=/dissolve/100/dx/50/dy/200
世界上最好的编程语言PHP图层裁剪服务搭建详解

 

5、压缩图片

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

压缩前

世界上最好的编程语言PHP图层裁剪服务搭建详解

 

压缩后

世界上最好的编程语言PHP图层裁剪服务搭建详解

 

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

接下来,分析下php如何才能实现以上功能

总体架构

世界上最好的编程语言PHP图层裁剪服务搭建详解

 

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

2、 浏览器发送请求

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

4、 根据请求加载原图片,并根据选择的接口生成最终图片

5、 返回给浏览器

实现步骤

1、 环境介绍

基于PHPstudy集成开发环境

域名:

项目目录: E:projectphpimage

开启 rewrite 重定向,优化URL

项目目录结构:

世界上最好的编程语言PHP图层裁剪服务搭建详解

 

2、图片上传

使用百度的 Web Uploader 上传图片即可,具体实现可以参考官网:

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

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

前端页面:

世界上最好的编程语言PHP图层裁剪服务搭建详解

 

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

3、 Rewrite 重定向

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

世界上最好的编程语言PHP图层裁剪服务搭建详解

 

它是通过 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
世界上最好的编程语言PHP图层裁剪服务搭建详解

 

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

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

关键函数: imagecopyresized

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

请求接口:http://www.image.com/26.jpg?imageView/1/w/100/h/140
世界上最好的编程语言PHP图层裁剪服务搭建详解

 

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

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

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

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

请求接口http://www.image.com/26.jpg?imageView/2/w/100/h/140
世界上最好的编程语言PHP图层裁剪服务搭建详解

 

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

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

从应用场景来说,模式0适合移动设备上做缩略图,模式2适合PC上做缩略图

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

请求接口http://www.image.com/26.jpg?imageView/3/w/100/h/140
世界上最好的编程语言PHP图层裁剪服务搭建详解

 

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

总结

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

世界上最好的编程语言PHP图层裁剪服务搭建详解

 

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

IT技术研习社,专注互联网技术研究与分享,喜欢的朋友可以点击【关注】;把经验传递给有梦想的人;

 



Tags:PHP 图层裁剪   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
概述每一个做过WEB程序开发的程序员(比如,博客、电商),应该都有这样的体验,有时候我们需要在不同的页面显示不同尺寸的图片,比如,首页、商品列表页、详情页,如下:首页 列表页 详...【详细内容】
2019-07-31  Tags: PHP 图层裁剪  点击:(230)  评论:(0)  加入收藏
▌简易百科推荐
序言:前段时间织梦因为版权的问题在网上闹得沸沸扬扬,也提醒了众多开发者选择cms上应该谨慎使用,今天给大家展示一款自己搭建的内容管理系统,不用担心版权的问题,而且非常容易维...【详细内容】
2021-11-30  小程序软件开发    Tags:管理系统   点击:(34)  评论:(0)  加入收藏
准备安装包(PHP: Hypertext Preprocessor)下载安装包以及组件wget https://www.php.net/distributions/php-8.0.0.tar.bz2wget https://github.com/phpredis/phpredis/archive...【详细内容】
2021-11-09  mimic96    Tags:PHP   点击:(40)  评论:(0)  加入收藏
golang context 很好用,就使用php实现了github地址 : https://github.com/qq1060656096/php-go-context context使用闭坑指南1. 将一个Context参数作为第一个参数传递给传入和...【详细内容】
2021-11-05  1060656096    Tags:PHP   点击:(41)  评论:(0)  加入收藏
一段数组为例:$list = array:4 [ 0 => array:7 [ "id" => 56 "mer_id" => 7 "order_id" => "wx163265961408769974" "is_postage" => 0 "store_name" => "奇...【详细内容】
2021-09-29  七七小影视    Tags:PHP   点击:(65)  评论:(0)  加入收藏
利用JS的CryptoJS 3.x和PHP的openssl_encrypt,openssl_decrypt实现AES对称加密解密,由于需要两种语言对同一字符串的操作,而CryptoJS 的默认加密方式为“aes-256-cbc”,PHP端也...【详细内容】
2021-09-16  李老师tome    Tags:对称加密   点击:(79)  评论:(0)  加入收藏
1、checkdate()验证格利高里日期即:日期是否存在。checkdate(month,day,year);month必需。一个从 1 到 12 的数字,规定月。day必需。一个从 1 到 31 的数字,规定日。year必需。...【详细内容】
2021-08-31  七七小影视    Tags:时间函数   点击:(80)  评论:(0)  加入收藏
对于各类开发语言来说,整数都有一个最大的位数,如果超过位数就无法显示或者操作了。其实,这也是一种精度越界之后产生的精度丢失问题。在我们的 PHP 代码中,最大的整数非常大,我...【详细内容】
2021-08-26  硬核项目经理    Tags:PHP   点击:(83)  评论:(0)  加入收藏
遵从所有教材以及各类数据结构相关的书书籍,我们先从线性表开始入门。今天这篇文章更偏概念,是关于有线性表的一个知识点的汇总。上文说过,物理结构是用于确定数据以何种方式存...【详细内容】
2021-07-19  硬核项目经理    Tags:线性表   点击:(94)  评论:(0)  加入收藏
一、开启IIS全部功能。二、部署PHP1.官网下载并解压PHP: https://windows.php.net/downloads/releases/2.将php.ini-development文件改为php.ini3.修改php.ini(1)去掉注释,并修...【详细内容】
2021-07-15  炘蓝火诗  今日头条  Tags:PHP环境   点击:(129)  评论:(0)  加入收藏
一、环境说明本文中使用本地VM虚机部署测试。OS:CentOS Linux release 7.8.2003 (Core)虚机配置:2核CPU、4G内存①系统为CentOS 7.8 x64最小化安装,部署前已完成系统初始化、...【详细内容】
2021-06-25  IT运维笔记  今日头条  Tags:PHP8.0.7   点击:(141)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条