带领大家一起做一个ThinkPHP整合jcrop图片上传裁切预览的例子

简介:

   发现经常有人在技术群里问要PHP图片上传裁切并且预览的例子。今天正好有时间,就亲自做了一个,同时把方法公布出来,让大家可以理解,学会如何用ThinkPHP+jcrop做这个例子。首先先下来jcrop,网址:http://deepliquid.com/content/Jcrop_Download.html

   下载完成后,里面有js,demo,css等文件夹.demo里是例子,建议大家先看一下源代码.剩下的,跟我一起来做这个例子:

   1.下载ThinkPHP,然后新建项目,生成项目目录

   2.在Tpl中新建Index/index.html

代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
< html >
< head >
< meta  http-equiv = "Content-Type"  content = "text/html; charset=utf-8" >
< title >上传图片</ title >
  < script >
      function setFile(f1){
         document.frm.logoImg.value=f1;
      }
     </ script >
</ head >
< body >
< table  border = "0"  align = "center"  cellpadding = "0"  cellspacing = "0" >
   < tr >
     < td  height = "45"  align = "center"  valign = "middle" >
         < form  action = "#"  method = "post"   name = "frm" > 请选择上传的图片
               < input  name = "logoImg"  id = "logoImg"    type = "text"  size = "30" />
              < label  style = "cursor:hand"  onClick = "window.open('__URL__/upimg','上传图片','height=600,width=800,top=200,left=200')" >上传图片</ label >< br />
         </ form >
     </ td >
   </ tr >
</ table >
</ body >
</ html >


这是一个上传,在点击上传图片以后,会弹出一个窗口,专门用来上传图片裁切。在Tpl/Index/下新建upimg.html

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE HTML PUBLIC  "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd" >
<html>
<head>
<meta http-equiv= "Content-Type"  content= "text/html; charset=utf-8" >
<title>上传图片</title>
<script language= "javascript" >
     function  $(id){
         return  document.getElementById(id);
     }
     function  ok(){
          $( "logoimg" ).src = $( "filename" ).value;
      }
</script>
</head>
<body>
<table border= "0"  align= "center"  cellpadding= "0"  cellspacing= "0" >
   <tr>
     <td height= "45"  align= "center"  valign= "middle" >
         <form action= "__URL__/uploadf?submit=1"  method= "post"  enctype= "multipart/form-data"  name= "form1" > 请选择上传的图片
             <input type= "file"  name= "filename"  id= "filename"  onchange= "ok()" >
             <!-- MAX_FILE_SIZE must precede the file input field -->
             <input type= "hidden"  name= "MAX_FILE_SIZE"  value= "30000"  />
             <input type= "submit"  name= "Submit"  value= "上传" >
         </form>
     </td>
   </tr>
</table>
</body>
</html>


我没有用TP自带的文件上传类,如果大家需要,可以改下,以上主要就是弹出一个上传文件的窗口,在这个窗口中会完成文件上传,裁切等操作。点击提交到Index/uploadf

Index/uploadf代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$path  "uploadfiles/" ;          //图片上传地址
                 if  (!  file_exists  $path  )) {
                     mkdir  "$path" , 0700 );
                 }
                 $tp  array  (
                         "image/gif" ,
                         "image/jpeg" ,
                         "image/png" ,
                         "image/jpg"
                 );
                                                                                                                                                                                                                                              
                 if  (! in_array (  $_FILES  [ "filename" ] [ "type" ],  $tp  )) {
                     echo  "格式不对" ;
                     exit  ();
                 // END IF
                                                                                                                                                                                                                                              
                 if  ( $_FILES  [ "filename" ] [ "name" ]) {
                     $file1  $_FILES  [ "filename" ] [ "name" ];
                     $file2  $path  . time () .  $file1 ;
                     $flag  = 1;
                 }
                                                                                                                                                                                                                                              
                 if  ( $flag )
                     $result  = move_uploaded_file (  $_FILES  [ "filename" ] [ "tmp_name" ],  $file2  );
                 if  ( $result ) {
                                                                                                                                                                                                                                          
                     $this ->assign( 'filename' , $file2 );
                     $this ->display();
                 }



上传完成以后会直接跳转到uploadf.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
< html >
< head >
< meta  http-equiv = "Content-Type"  content = "text/html; charset=UTF-8" >
< title >Insert title here</ title >
</ head >
< script  src = "__STYLE__/js/jquery.min.js" ></ script >
< script  src = "__STYLE__/js/jquery.Jcrop.js" ></ script >
< link  rel = "stylesheet"  href = "__STYLE__/css/main.css"  type = "text/css"  />
< link  rel = "stylesheet"  href = "__STYLE__/css/demos.css"  type = "text/css"  />
< link  rel = "stylesheet"  href = "__STYLE__/css/jquery.Jcrop.css"  type = "text/css"  />
< script  language = 'javascript' >
     jQuery(function($) {
         var jcrop_api, boundx, boundy,
         $preview = $('#preview-pane'), $pcnt = $('#preview-pane .preview-container'), $pimg = $('#preview-pane .preview-container img'),
         xsize = $pcnt.width(), ysize = $pcnt.height();
         console.log('init', [ xsize, ysize ]);
         $('#target').Jcrop({
             onChange : updatePreview,
             onSelect : updatePreview,
             aspectRatio : xsize / ysize
         }, function() {
             var bounds = this.getBounds();
             boundx = bounds[0];
             boundy = bounds[1];
             jcrop_api = this;
             $preview.appendTo(jcrop_api.ui.holder);
         });
         function updatePreview(c) {
             if (parseInt(c.w) > 0) {
                 var rx = xsize / c.w;
                 var ry = ysize / c.h;
                 $pimg.css({
                     width : Math.round(rx * boundx) + 'px',
                     height : Math.round(ry * boundy) + 'px',
                     marginLeft : '-' + Math.round(rx * c.x) + 'px',
                     marginTop : '-' + Math.round(ry * c.y) + 'px'
                 });
                                                                                                                                                                                                                                    
                 $('#x').val(c.x);
                 $('#y').val(c.y);
                 $('#w').val(c.w);
                 $('#h').val(c.h);
             }
         }
         ;
         function updateCoords(c){
                                                                                                                                                                                                                                    
             };
                                                                                                                                                                                                                                
     });
</ script >
< style  type = "text/css" >
.jcrop-holder #preview-pane {
     display: block;
     position: absolute;
     z-index: 2000;
     top: 10px;
     right: -240px;
     padding: 6px;
     border: 1px rgba(0, 0, 0, .4) solid;
     background-color: white;
     -webkit-border-radius: 6px;
     -moz-border-radius: 6px;
     border-radius: 6px;
     -webkit-box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.2);
     -moz-box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.2);
     box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.2);
}
#preview-pane .preview-container {
     width: 170px;
     height: 250px;
     overflow: hidden;
}
</ style >
< body >
     < div  class = "container" >
         < div  class = "row" >
             < div  class = "span12" >
                 < div  class = "jc-demo-box" >
                     < img  src = "__ROOT__/{$filename}"  id = "target"  alt = "[Jcrop Example]"  />
                     < div  id = "preview-pane" >
                         < div  class = "preview-container" >
                             < img  src = "__ROOT__/{$filename}"  class = "jcrop-preview"
                                 alt = "Preview"  />
                         </ div >
                     </ div >
                     < div  class = "clearfix" ></ div >
                 </ div >
             </ div >
         </ div >
     </ div >
     < form  action = "__URL__/uploadf?submit=cut"  method = "post"  onsubmit = "return checkCoords();" >
             < input  type = "hidden"  id = "x"  name = "x"  />
             < input  type = "hidden"  id = "y"  name = "y"  />
             < input  type = "hidden"  id = "w"  name = "w"  />
             < input  type = "hidden"  id = "h"  name = "h"  />
             < input  type = "hidden"  name = "filename"  value = "{$filename}" >
             < input  type = "submit"  value = "Crop Image"  />
         </ form >
     <!--     <img src="__ROOT__/{$filename}" alt="" /> -->
</ body >
</ html >



这里的代码比较长,慢慢解释吧,我直接复制的jcrop demo里的tutorial3.html,加载他自己需要的js,css。其中

1
2
3
4
5
#preview-pane .preview-container {
     width: 170px;
     height: 250px;
     overflow: hidden;
}


这部分CSS会影响到出来的裁切框的比例。以及预览处的大小。

1
2
3
4
5
6
7
8
9
10
11
$( '#target' ).Jcrop({
             onChange : updatePreview,
             onSelect : updatePreview,
             aspectRatio : xsize / ysize
         },  function () {
             var  bounds =  this .getBounds();
             boundx = bounds[0];
             boundy = bounds[1];
             jcrop_api =  this ;
             $preview.appendTo(jcrop_api.ui.holder);
         });



onChange和onSelect处的意思是裁切的时候要执行的js代码,说实话,我js和jq的水平很垃圾。所以不管了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function  updatePreview(c) {
             if  (parseInt(c.w) > 0) {
                 var  rx = xsize / c.w;
                 var  ry = ysize / c.h;
                 $pimg.css({
                     width : Math.round(rx * boundx) +  'px' ,
                     height : Math.round(ry * boundy) +  'px' ,
                     marginLeft :  '-'  + Math.round(rx * c.x) +  'px' ,
                     marginTop :  '-'  + Math.round(ry * c.y) +  'px'
                 });
                                                                                                                                                                 
                 $( '#x' ).val(c.x);
                 $( '#y' ).val(c.y);
                 $( '#w' ).val(c.w);
                 $( '#h' ).val(c.h);
             }
         }
         ;


这个后面我自己加了一个赋值,赋值给form表单中。然后在提交到php完成裁切工作


点击提交到uploadf中,可以自己先写一个图片裁切的类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<?php
class  Imgshot {
     private  $filename ;
     private  $ext ;
     private  $x ;
     private  $y ;
     private  $x1 ;
     private  $y1 ;
     private  $width  = 170;
     private  $height  = 250;
     private  $jpeg_quality  = 90;
     /**
      * 构造器
      */
     public  function  __construct() {
//      log_message ( 'debug', "Img_shot Class Initialized" );
     }
     /**
      * 初始化截图对象
      *
      * @param
      *          filename 源文件路径全明
      * @param
      *          width 截图的宽
      * @param
      *          height 截图的高
      * @param
      *          x 横坐标1
      * @param
      *          y 纵坐标1
      * @param
      *          x1 横坐标1
      * @param
      *          y1 横坐标2
      *        
      */
     public  function  initialize( $filename $x $y $x1 $y1 ) {
         if  ( file_exists  $filename  )) {
             $this ->filename =  $filename ;
             $pathinfo  pathinfo  $filename  );
             $this ->ext =  $pathinfo  [ 'extension' ];
         else  {
             $e  new  Exception (  'the file is not exists!' , 1050 );
             throw  $e ;
         }
         $this ->x =  $x ;
         $this ->y =  $y ;
         $this ->x1 =  $x1 ;
         $this ->y1 =  $y1 ;
     }
     /**
      * 生成截图
      * 根据图片的格式,生成不同的截图
      */
     public  function  generate_shot() {
         switch  ( $this ->ext) {
             case  'jpg'  :
                 return  $this ->generate_jpg ();
                 break ;
             case  'png'  :
                 return  $this ->generate_png ();
                 break ;
             case  'gif'  :
                 return  $this ->generate_gif ();
                 break ;
             default  :
                 return  false;
         }
     }
     /**
      * 得到生成的截图的文件名
      */
     private  function  get_shot_name() {
         $pathinfo  pathinfo  $this ->filename );
         $fileinfo  explode  '.' $pathinfo  [ 'basename' ] );
         $filename  $fileinfo  [0] .  '_small.'  $this ->ext;
         return  'uploadfiles/' . $filename ;
     }
     /**
      * 生成jpg格式的图片
      */
     private  function  generate_jpg() {
         $shot_name  $this ->get_shot_name ();
         $img_r  = imagecreatefromjpeg (  $this ->filename );
         $dst_r  = ImageCreateTrueColor (  $this ->width,  $this ->height );
                                                                                                      
         imagecopyresampled (  $dst_r $img_r , 0, 0,  $this ->x,  $this ->y,  $this ->width,  $this ->height,  $this ->x1,  $this ->y1 );
         imagejpeg (  $dst_r $shot_name $this ->jpeg_quality );
         return  $shot_name ;
     }
     /**
      * 生成gif格式的图片
      */
     private  function  generate_gif() {
         $shot_name  $this ->get_shot_name ();
         $img_r  = imagecreatefromgif (  $this ->filename );
         $dst_r  = ImageCreateTrueColor (  $this ->width,  $this ->height );
                                                                                                      
         imagecopyresampled (  $dst_r $img_r , 0, 0,  $this ->x,  $this ->y,  $this ->width,  $this ->height,  $this ->x1,  $this ->y1 );
         imagegif (  $dst_r $shot_name  );
         return  $shot_name ;
     }
     /**
      * 生成png格式的图片
      */
     private  function  generate_png() {
         $shot_name  $this ->get_shot_name ();
         $img_r  = imagecreatefrompng (  $this ->filename );
         $dst_r  = ImageCreateTrueColor (  $this ->width,  $this ->height );
                                                                                                      
         imagecopyresampled (  $dst_r $img_r , 0, 0,  $this ->x,  $this ->y,  $this ->width,  $this ->height,  $this ->x1,  $this ->y1 );
         imagepng (  $dst_r $shot_name  );
         return  $shot_name ;
     }
}
?>



这个是我在网上down的.~没自己写,自己可以根据需求扩展一下.


裁切操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
     $filename = $this ->cut();
                 echo  "<script language='javascript'>" ;
                 echo  "alert(\"上传成功!\");" ;
                 echo  "</script>" ;
                 echo  ( "<input type=\"button\" name=\"Submit\" value=\"确定\" onClick=\"window.opener.setFile('"  . $filename "');window.close();\">" );
                 echo  '<img src="' .__ROOT__. '/' . $filename . '" alt="" />' ;
//裁切的方法
     function  cut(){
         import( 'ORG.Net.Imgshot' );
         $imgshot = new  Imgshot();
         $imgshot ->initialize(SITE_PATH. '/' . $_REQUEST [ 'filename' ],  $_REQUEST [ 'x' ],  $_REQUEST [ 'y' ],  $_REQUEST [ 'x' ]+ $_REQUEST [ 'w' ],  $_REQUEST [ 'y' ]+ $_REQUEST [ 'h' ]);
         $filename = $imgshot ->generate_shot();
         return  $filename ;
     }



完成以后会直接echo出最后裁切的图片,并且还有一个确定按钮,点击确定以后,则会把裁切后图像的地址返回到最一开始的input[type="text"]。整个例子我还没有完善,大家可以根据需要自己去理解和完善。好了,如果不会的朋友可以加群:252799167问我。整个例子我已经发布到ThinkPHP的官网,大家可以下载。

http://www.thinkphp.cn/topic/9154.html










本文转自 3147972 51CTO博客,原文链接:http://blog.51cto.com/a3147972/1336561,如需转载请自行联系原作者
目录
相关文章
|
6月前
|
小程序 开发者
【微信小程序-原生开发】实用教程05-首页(含自定义调试模式、插入图片、图文排版、底部留白、添加本地图片)
【微信小程序-原生开发】实用教程05-首页(含自定义调试模式、插入图片、图文排版、底部留白、添加本地图片)
79 0
|
8月前
如何利用 HBuilderX 制作图文混排的网页
如何利用 HBuilderX 制作图文混排的网页
344 3
|
小程序 前端开发
微信小程序_自定义markdown的图片点击放大处理
微信小程序_自定义markdown的图片点击放大处理
416 0
|
JavaScript 开发者
ElUpload不好用?一文教你实现一个简易图片上传预览组件
ElUpload不好用?一文教你实现一个简易图片上传预览组件
2501 0
|
程序员
程序员PS技能(四):程序员创建PSD文件、展示简单PSD设计流程,上传PSD至蓝湖,并下载Demo切图
程序员PS技能(四):程序员创建PSD文件、展示简单PSD设计流程,上传PSD至蓝湖,并下载Demo切图
程序员PS技能(四):程序员创建PSD文件、展示简单PSD设计流程,上传PSD至蓝湖,并下载Demo切图
|
存储 移动开发 小程序
如何实现微信小程序图像剪切?代码拿去用,不谢!
我在早先发布的文章《如何实现微信小程序换头像?三步帮你搞定!》中,提到实现微信小程序换头像需要三步: 获取用户头像 图片模板 图片合成 前文已经就获取用户头像和图片模板两个步骤进行了讲解,本文就来详细说说如何合成图片。图片合成的过程中非常重要的一块功能对图片进行剪切。该功能点很固定,大都是对图片进行拖拽、缩放后,在一定区域内剪切出一个固定长宽的图片。这类功能在app端和H5中都有很多成熟的插件供使用,接下来就来看看我在海豚趣图小程序中的头像剪切插件是如何实现的,欢迎大家提意见。
|
缓存 Java Linux
网页截图和svg模版动态生成图片Java实现(3)
网页截图和svg模版动态生成图片Java实现(3)
236 0
网页截图和svg模版动态生成图片Java实现(3)
|
移动开发 Java Linux
网页截图和svg模版动态生成图片Java实现(2)
网页截图和svg模版动态生成图片Java实现(2)
433 0
网页截图和svg模版动态生成图片Java实现(2)
|
移动开发 Java 应用服务中间件
网页截图和svg模版动态生成图片Java实现(1)
网页截图和svg模版动态生成图片Java实现(1)
521 0
网页截图和svg模版动态生成图片Java实现(1)
|
缓存 开发框架 Kubernetes
Abp小试牛刀之 图片上传
图片上传是很常见的功能,里面有些固定的操作也可以沉淀下来。 本文记录使用Abp vNext做图片上传的姿势。
Abp小试牛刀之 图片上传