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

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

此时已经取得了裁剪的坐标,只需将坐标传回服务器交给脚本处理,使用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. $arr = getimagesize('/picture/'.$file['name']);
  3. $strarr = explode("\"",$arr[3]);//分析图片宽高
  4. $data = array(
  5. 'filename'=>$file['name'],
  6. 'width'=>$strarr[1],
  7. 'height'=>$strarr[3]
  8. );
  9. 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. if ($x > $tw || $y > $th || $w > $tw || $h > $th)
  5. return FALSE;
  6. $temp = imagecreatetruecolor($w, $h);
  7. imagecopyresampled($temp, $image, 0, 0, $x, $y,
  8. $w, $h, $w, $h);
  9. return $temp;
  10. }
  11. $pic = '/picture/'.$_POST['name'];
  12. $cutPosition = json_decode($_POST['position']);  //取得上传的数据
  13. $x1 = $cutPosition->x1;
  14. $y1 = $cutPosition->y1;
  15. $width = $cutPosition->width;
  16. $height = $cutPosition->height;
  17. $type=exif_imagetype($pic);  //判断文件类型
  18. $support_type=array(IMAGETYPE_JPEG , IMAGETYPE_PNG , IMAGETYPE_GIF);
  19. if(!in_array($type, $support_type,true)) {
  20. echo "this type of image does not support! only support jpg , gif or png";
  21. exit();
  22. }
  23. switch($type) {
  24. case IMAGETYPE_JPEG :
  25. $image = imagecreatefromjpeg($pic);
  26. break;
  27. case IMAGETYPE_PNG :
  28. $image = imagecreatefrompng($pic);
  29. break;
  30. case IMAGETYPE_GIF :
  31. $image = imagecreatefromgif($pic);
  32. break;
  33. default:
  34. echo "Load image error!";
  35. exit();
  36. }
  37. $copy = PIPHP_ImageCrop($image, $x1, $y1, $width, $height);//裁剪
  38. $targetPic = '/picture/cut/'.$_POST['name'];
  39. imagejpeg($copy, $targetPic);  //输出新图
  40. @unlink($pic);//删除原图节省空间
  41. echo $_POST['pic'].'?'.time(); //返回新图地址

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

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

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

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

  via csdn

Uploadify & jQuery.imgAreaSelect 插件实现图片上传裁剪的更多相关文章

  1. 图片上传裁剪zyupload

    图片上传控件用的是zyupload控件,使用过程中遇到了一些问题,特别记录下来 上图是目前的使用效果,这个控件我是用js代码动态添加出来的 HTML代码: <div class="wi ...

  2. JQuery插件:图片上传本地预览插件,改进案例一则。

    /* *名称:图片上传本地预览插件 v1.1 *作者:周祥 *时间:2013年11月26日 *介绍:基于JQUERY扩展,图片上传预览插件 目前兼容浏览器(IE 谷歌 火狐) 不支持safari *插 ...

  3. Jquery插件-Html5图片上传并裁剪

    /** * 图片裁剪 * @author yanglizhe * 2015/11/16 */ (function($){ /** * Drag */ var Drag={obj:null,init:f ...

  4. springmvc集成Ueditor插件实现图片上传2、

    一.下载Ueditor插件. 地址:http://ueditor.baidu.com/website/download.html 二.环境搭建. 具体可以参看http://fex.baidu.com/ ...

  5. jQuery:[1]实现图片上传并预览

    jQuery:[1]实现图片上传并预览 原理 预览思路 1.当上传对象的input被触发并选择本地图片之后获取要上传的图片对象的URL: 2.把对象URL赋值给实现写好的img标签的src属性 Fil ...

  6. 基于Jcrop的图片上传裁剪加预览

    最近自己没事的时候研究了下图片上传,发现之前写的是有bug的,这里自己重新写了一个! 1.页面结构 <!DOCTYPE html> <html lang="en" ...

  7. jquery插件fileupload图片上传(前端如何处理)

    1.页面首先引入jquery,版本不要低于1.6 <script src="../js/jquery.min.js"></script>2.其次页面引入对应 ...

  8. jquery php ajax多图片上传.上传进度,生成缩略图

    本例用到其他2个php class.upload.php和 functions.php还有css和js以及img文件 下载地址为www.freejs.net/demo/91/down.zip 演示 J ...

  9. jquery+html5实现单张图片上传预览

    js: if (window.File && window.FileReader && window.FileList && window.Blob){ ...

随机推荐

  1. C#高级编程 (第六版) 学习 第三章:对象和类型

    第三章 对象和类型 1,类和结构 类存储在托管堆上 结构存储在堆栈上   2,类成员 类中的数据和函数称为类成员 数据成员 数据成员包括了字段.常量和事件   函数成员 方法:与某个类相关的函数,可以 ...

  2. TCP系列48—拥塞控制—11、FRTO拥塞撤销

    一.概述 FRTO虚假超时重传检测我们之前重传章节的文章已经介绍过了,这里不再重复介绍,针对后面的示例在说明两点 1.FRTO只能用于虚假超时重传的探测,不能用于虚假快速重传的探测. 2.延迟ER重传 ...

  3. 在.net项目中使用Consul

    1.创建.net core web程序并运行 2.在Consul中注册该服务 Consul支持两种服务注册的方式,一种是通过Consul的服务注册HTTP API,由服务自身在启动后调用API注册自己 ...

  4. CentOS yum 安装LAMP PHP5.4版本

    CentOS yum 安装LAMP PHP5.4版本 [日期:2015-06-04] 来源:Linux社区  作者:rogerzhanglijie [字体:大 中 小]     Linux系统版本:C ...

  5. google auth

    思路: secret 系统生成的密钥 把密钥分配给某个用户,用户可以把这个密钥加入到app中,app会1min生成一个code: 验证时,根据用户的 secret ,系统生成一个code,再比较用户输 ...

  6. Maven学习——1、安装与修改Maven的本地仓库路径

    1.1.下载 官网 http://maven.apache.org/download.cgi 1.2.安装配置 apache-maven-3.3.3-bin.zip 解压下载的压缩包 1.3.配置环境 ...

  7. bzoj4754[JSOI2016]独特的树叶

    这个题....别人写得怎么都....那么短啊? 我怎么....WA了好几次啊....怎么去loj扒了数据才调出来啊? 这个算法...怎么我还是不知道对不对啊 怎么回事啊怎么回事啊怎么回事啊? 请无视上 ...

  8. 转---Post/Redirect/Get pattern

    今天重新认识了Post/Redirect/Get pattern, 感谢hip-hop的session, 一下帮助我理清了概念和思路. 谈到pattern,首先要清楚它为了什么而产生: PRG (参见 ...

  9. P1053 篝火晚会

    题目描述 佳佳刚进高中,在军训的时候,由于佳佳吃苦耐劳,很快得到了教官的赏识,成为了“小教官”.在军训结束的那天晚上,佳佳被命令组织同学们进行篝火晚会.一共有nnn个同学,编号从111到nnn.一开始 ...

  10. [JSOI2009]游戏 二分图博弈

    题面 题面 题解 二分图博弈的模板题,只要会二分图博弈就可以做了,可以当做板子打. 根据二分图博弈,如果一个点x在某种方案中不属于最大匹配,那么这是一个先手必败点. 因为对方先手,因此我们就是要找这样 ...