zoukankan      html  css  js  c++  java
  • Uploadify & jQuery.imgAreaSelect 插件实现图片上传裁剪

      在网站中需要一个图片上传裁剪的功能,借鉴这篇文章 Ajax+PHP+jQuery图片截图上传 的指点,找到了jquery.imgAreaSelect这个不错插件,能对图片进行自定义区域选择并给出坐标,类似微博等同类网站上传头像要求按比例裁剪的功能,正合适就自己做了个。

    QQ截图20130914160306

    文件上传类经常使用到一个叫uploadify的插件,上面提到的文章也结合了uploadify插件的使用,只是现在版本的uploadify一些配置和方法已经改变了(3.2.1版本)。包括jquery.imgareaselect的一些API也有新的变化,在做的过程中通过查询文档才确认了一些功能和配置的用法。

    下面是两个插件的地址

    uploadify: http://www.uploadify.com/ ( 有 uploadifive(HTML5) 版本和 Flash 版本,顾及不支持HTML5的浏览器,目前建议选择Flash版本 )

    jquery.imgareaselect: http://odyniec.net/projects/imgareaselect ( 需先有 jQuery )

    具体的流程都相似,客户端uploadify替代表单接收原图,异步上传到服务器,服务器端接收后存储并返回图片文件名,取得文件名后可在浏览器显示出原图,这时在图片元素上配置imgareaselect使其可划定裁剪区域,划定结束后坐标传回服务器,PHP脚本接收换算后的坐标对原图进行裁剪。上面提到的文章中有详细的流程图,作者非常细心。下面说说我写的过程:

    上细节:首先是前端的配置 demo.php:

    1. $field = $("input[type='file']");  
    2. $field.uploadify({//配置uploadify  
    3.     'buttonText''选择图片',  //选择按钮显示的字符  
    4.     'swf'       : '/uploadify/uploadify.swf'//swf文件的位置  
    5.     'uploader'  : '/receivePic.php'//上传的接收者  
    6.     'cancelImg' : '/uploadify/uploadify-cancel.png',  
    7.     'folder'    : '/picture',//上传图片的存放地址  
    8.     'auto'      : false,    //选择图片后是否自动上传  
    9.     'multi'     : false,   //是否允许同时选择多个(false一次只允许选中一张图片)  
    10.     'method'    : 'post',  
    11.     'queueSizeLimit' : 1,//最多能选择加入的文件数量  
    12.     'fileTypeExts''*.gif; *.jpg; *.png'//允许的后缀  
    13.     'fileTypeDesc''Image Files'//允许的格式,详见文档  
    14.    
    15.     'onSelect'function(file) {//选择文件后的触发事件  
    16.         $("a.xtPicSubmit").show().click(function(){//自定义的按钮,显示点击执行上传  
    17.             $field.uploadify('upload','*');//此处触发上传  
    18.         });  
    19.         $wrap.find("p.picInfo span").text(file.name);//file.name为选中的图片名称      
    20.     },  
    21.    
    22.     'onUploadSuccess' : function(file, data, response) {  //上传成功后的触发事件  
    23.         $field.uploadify('disable'true);  //(上传成功后)'disable'禁止再选择图片  
    24.         data = JSON.parse(data);  //data为接收方(receivePic.php)返回的数据,稍后描述  
    25.    
    26. //此时开始对取回的数据处理出需要的图片名,宽高,并计算出原图比例尺,开始设定裁剪需要的计算量  
    27.    
    28.         var orignW = data.width,//存储原图的宽高,用于计算  
    29.             orignH = data.height,  
    30.             aspectRatio = JSON.parse(picFormat)[index].width/JSON.parse(picFormat)[index].height,//提前设定的裁剪宽高比,规定随后裁剪的宽高比例  
    31.             frameW = 260,  //原图的缩略图固定宽度,作为一个画布,限定宽度,高度自适应,保证了原图比例  
    32.             frameH = 0,  
    33.             prevFrameW = 140,  //预览图容器的高宽,宽度固定,高为需要裁剪的宽高比决定  
    34.             prevFrameH = 140/aspectRatio,  
    35.             rangeX   = 1,  //初始缩放比例  
    36.             rangeY   = 1,  
    37.             prevImgW = prevFrameW,  //初始裁剪预览图宽高  
    38.             prevImgH = prevFrameW;  
    39.    
    40.         $imgTar = $wrap.find("img.pic"),  //画布  
    41.         $imgCut = $cut.find("img.cutImg");//预览图  
    42.    
    43.         $imgTar.attr("src","/Picture/"+data.filename);//显示已上传的图片,此时图片已在服务器上  
    44.         frameH = Math.round(frameW*orignH/orignW);//根据原图宽高比和画布固定宽计算画布高,即$imgTar加载上传图后的高。此处不能简单用.height()获取,有DOM加载的延迟  
    45.         $cut.find(".preview").css('height',Math.round(prevFrameH)+"px");//设置裁剪后的预览图的容器高,注意此时的高度应由裁剪宽高比决定,而非原图宽高比  
    46.    
    47. //准备存放图片数据的变量,便于传回裁剪坐标  
    48.         CutJson.name = data.filename;  
    49.         CutJson.position = {};  
    50.    
    51. //准备好数据后,开始配置imgAreaSelect使得图片可选区  
    52.         var imgArea = $imgTar.imgAreaSelect({ //配置imgAreaSelect  
    53.             instance: true,  //配置为一个实例,使得绑定的imgAreaSelect对象可通过imgArea来设置  
    54.             handles: true,   //选区样式,四边上8个方框,设为corners 4个  
    55.             fadeSpeed: 300, //选区阴影建立和消失的渐变  
    56.             aspectRatio:'1:'+(1/aspectRatio), //比例尺  
    57.    
    58.             onSelectChange: function(img,selection){//选区改变时的触发事件  
    59.             /*selection包括x1,y1,x2,y2,width,height几个量,分别为选区的偏移和高宽。*/  
    60.                 rangeX   = selection.width/frameW;  //依据选取高宽和画布高宽换算出缩放比例  
    61.                 rangeY   = selection.height/frameH;  
    62.                 prevImgW = prevFrameW/rangeX; //根据缩放比例和预览图容器高宽得出预览图的高宽  
    63.                 prevImgH = prevFrameH/rangeY;  
    64.    
    65. //实时调整预览图预览裁剪后效果,可参见http://odyniec.net/projects/imgareaselect/ 的Live Example  
    66.                 $imgCut.css({  
    67.                     'width' : Math.round(prevImgW)+"px",  
    68.                     'height' : Math.round(prevImgH)+"px",  
    69.                     'margin-left':"-"+Math.round((prevFrameW/selection.width)*selection.x1)+"px",  
    70.                     'margin-top' :"-"+Math.round((prevFrameH/selection.height)*selection.y1)+"px"  
    71.                    
    72.                 });  
    73.             },  
    74.             onSelectEnd: function(img,selection){//放开选区后的触发事件  
    75.                 //计算实际对于原图的裁剪坐标  
    76.                 CutJson.position.x1 = Math.round(orignW*selection.x1/frameW);  
    77.                 CutJson.position.y1 = Math.round(orignH*selection.y1/frameH);  
    78.                 CutJson.position.width  = Math.round(rangeX*orignW);  
    79.                 CutJson.position.height = Math.round(rangeY*orignH);  
    80.             }  
    81.         });  
    82.     }  
    83. });  

    此时已经取得了裁剪的坐标,只需将坐标传回服务器交给脚本处理,使用jQuery的ajax方法回传数据:

    1. $("a.getCut").click(function(){  
    2.     $.ajax({  
    3.         type: "POST",  
    4.     url : "cutPic.php",  
    5.     data: { name:data.filename,position:JSON.stringify(CutJson.position) },  
    6.     success: function(data){  
    7.     $imgTar.attr('src',"/picture/cut/"+data); //裁剪成功传回生成的新图文件名,将结果图显示到页面  
    8.     }  
    9.    });  
    10. });  


    至此前端的处理就基本完成了(代码省去了一些状态显示,元素变化的处理细节),下面是后端的两个脚本:

    首先是接收上传图片的脚本,接收并存储图片后返回图片数据:

    receivePic.php

    1. //上传文件处理代码与往常相同,此处省去..  
    2.    
    3. $arr = getimagesize('/picture/'.$file['name']);  
    4. $strarr = explode(""",$arr[3]);//分析图片宽高  
    5. $data = array(  
    6.      'filename'=>$file['name'],  
    7.      'width'=>$strarr[1],  
    8.      'height'=>$strarr[3]  
    9.  );  
    10. echo json_encode($data);  


    接下来是裁剪,其中也用到了PIPHP_ImageCrop裁剪函数

    cutPic.php:

    1. function PIPHP_ImageCrop($image$x$y$w$h){  
    2.    $tw = imagesx($image);  
    3.    $th = imagesy($image);  
    4.    
    5.    if ($x > $tw || $y > $th || $w > $tw || $h > $th)  
    6.       return FALSE;  
    7.    
    8.    $temp = imagecreatetruecolor($w$h);  
    9.    imagecopyresampled($temp$image, 0, 0, $x$y,  
    10.       $w$h$w$h);  
    11.    return $temp;  
    12. }  
    13.    
    14. $pic = '/picture/'.$_POST['name'];  
    15. $cutPosition = json_decode($_POST['position']);  //取得上传的数据  
    16. $x1 = $cutPosition->x1;  
    17. $y1 = $cutPosition->y1;  
    18. $width = $cutPosition->width;  
    19. $height = $cutPosition->height;  
    20.    
    21. $type=exif_imagetype($pic);  //判断文件类型  
    22. $support_type=array(IMAGETYPE_JPEG , IMAGETYPE_PNG , IMAGETYPE_GIF);  
    23. if(!in_array($type$support_type,true)) {  
    24.     echo "this type of image does not support! only support jpg , gif or png";  
    25.     exit();  
    26. }  
    27. switch($type) {  
    28.             case IMAGETYPE_JPEG :  
    29.                 $image = imagecreatefromjpeg($pic);  
    30.                 break;  
    31.             case IMAGETYPE_PNG :  
    32.                 $image = imagecreatefrompng($pic);  
    33.                 break;  
    34.             case IMAGETYPE_GIF :  
    35.                 $image = imagecreatefromgif($pic);  
    36.                 break;  
    37.             default:  
    38.                 echo "Load image error!";  
    39.                 exit();  
    40. }  
    41.    
    42. $copy = PIPHP_ImageCrop($image$x1$y1$width$height);//裁剪  
    43.    
    44. $targetPic = '/picture/cut/'.$_POST['name'];  
    45.    
    46. imagejpeg($copy$targetPic);  //输出新图  
    47.    
    48. @unlink($pic);//删除原图节省空间  
    49.    
    50. echo $_POST['pic'].'?'.time(); //返回新图地址  

    整个过程就完成了。上个效果图:

    QQ截图20130914160306

    开始的部分很多参考了Ajax+PHP+jQuery图片截图上传 此篇详细的文章,这里再次说明。

    后端的交互很轻松,任务主要在于前端两个插件之间的搭建和使用,我的代码写的比较仓促,应该需要更加结构化一点。另外上传文件的各方面控制也是一个风险(类型,大小等),值得更多的考虑。

      本文链接:http://www.cnblogs.com/oooweb/p/uploadify-jquery-image-cropper.html

      via csdn

  • 相关阅读:
    数据结构、算法、及线性表总结
    第二次博客作业: 函数+进制转换器v1.0beta
    c语言文件
    Oracle中Left Outer Join和外关联(+)的区别
    Oracle中trunc函数、round 函数、ceil函数和floor 函数的使用
    Oracle 表之间的连接 JOIN
    Oracle TRUNCATE语法
    使用Content editor webpart 为NewForm增加默认值
    Metadata serviceTaxonomyHiddenList 权限
    SQL server总是不能远程连接
  • 原文地址:https://www.cnblogs.com/oooweb/p/uploadify-jquery-image-cropper.html
Copyright © 2011-2022 走看看