jQuery+PHP实现上传裁剪图片


Posted in jQuery onJune 29, 2020

本文是一个简单的jquery图片预览+裁剪的例子,原理是在前端获取要裁剪的信息,如宽高比、裁剪坐标,上传图片之后在后端php进行切割

jquery代码(必须在最后面引入)

function showCutImg(showImg){
   var showImg = $(showImg);
   var changeInput = showImg.parents('.showImgDiv').siblings('.CutImage');
   var size = changeInput.siblings('.imgCoord').attr('ratio').split('*');
   var needWidth = size[0];
   var needHeight = size[1];
   var ratio = parseInt(needWidth)/parseInt(needHeight);
   ratio = parseFloat(ratio.toFixed(2));
   var thisFullDiv = showImg.parent();
   var coordArr = changeInput.siblings('.imgCoord').val().split(',');

   thisCutImgWidth = showImg.width();
   thisCutImgHeight = showImg.height()

   thisFullDiv.css('width',thisCutImgWidth);
   thisFullDiv.css('height',thisCutImgHeight);

   if((thisCutImgWidth/thisCutImgHeight)>=ratio){
    var thisCutDivHeight = thisCutImgHeight;
    var thisCutDivWidth = thisCutDivHeight*ratio;
   }else{
    var thisCutDivWidth = thisCutImgWidth;
    var thisCutDivHeight = thisCutDivWidth/ratio;
   }

   var hideWidth = (thisFullDiv.width()-thisCutDivWidth)/2;

   showImg.siblings('.hideImgLeft').width(hideWidth);
   showImg.siblings('.hideImgRight').width(hideWidth);

   var hideHeight = (thisFullDiv.height()-thisCutDivHeight)/2;

   showImg.siblings('.hideImgTop').width(thisCutDivWidth);
   showImg.siblings('.hideImgBottom').width(thisCutDivWidth);

   showImg.siblings('.hideImgTop').height(hideHeight);
   showImg.siblings('.hideImgBottom').height(hideHeight);

   if(hideWidth>0){
    var cutRatioX = thisCutImgWidth/hideWidth;
   }else{
    var cutRatioX = 0
   }

   if(hideHeight>0){
    var cutRatioY = thisCutImgHeight/hideHeight;
   }else{
    var cutRatioY = 0;
   }

   var coord = needWidth+'#'+needHeight+'#'+(cutRatioX)+'#'+(cutRatioY);

   if(coordArr!=''){
    coordArr.push(coord);
   }else{
    coordArr = [coord];
   }

   changeInput.siblings('.imgCoord').val(coordArr);
   $('.fullDiv').on('mousedown',function(e){
    var me = $(this);

    var changeInput = me.parent().siblings('.CutImage');

    var index = me.attr('index');

    var oldx = e.pageX;
    var oldy = e.pageY;

    var imgleft = me.children('.cutImg').position().left;
    var imgtop = me.children('.cutImg').position().top;

    var maxw = me.children('.hideImgLeft').width();
    var maxh = me.children('.hideImgTop').height();

    var goordArr = changeInput.siblings('.imgCoord').val().split(',');

    var cutDivSize = goordArr[index].split('#');

    $(document).mousemove(function(e){
     var newx = e.pageX;
     var newy = e.pageY;

     var movex = newx - oldx;
     var movey = newy - oldy;

     var x = movex + imgleft;
     var y = movey + imgtop;

     if(Math.abs(x)>maxw){
      if(x>0) x = maxw;
      if(x<0) x = -maxw;
     }

     if(Math.abs(y)>maxh){
      if(y>0) y = maxh;
      if(y<0) y = -maxh;
     }

     me.children('.cutImg').css('left',x+'px');
     me.children('.cutImg').css('top',y+'px');

     if(parseInt(maxw - x)>0){
      var cutRatioX = me.children('.cutImg').width()/parseInt(maxw - x);
     }else{
      var cutRatioX = 0;
     }

     if(parseInt(maxh - y)>0){
      var cutRatioY = me.children('.cutImg').height()/parseInt(maxh - y)
     }else{
      var cutRatioY = 0;
     }

     var cutImgPo = (cutRatioX) +'#'+ (cutRatioY);

     var coordVal = cutDivSize[0]+'#'+cutDivSize[1]+'#'+cutImgPo;

     goordArr[index] = coordVal;

     changeInput.siblings('.imgCoord').val(goordArr);


    });
   });


   $(document).on('mouseup',function(e){
    $(document).unbind('mousemove');
   });
  }



  $(".CutImage").change(function(){

   $(this).siblings('.imgCoord').val('');

   if($(this).prop('multiple')!=true){  //判断是否多文件上传
    var objUrl = getObjectURL1(this.files[0]) ;

    var showImgWidth = $(this).siblings('.showImgDiv').attr('showImgWidth');

    if(!showImgWidth)
    {
     showImgWidth = '150';
    }

    if (objUrl) {
      html = '';
      html += '<div style="border:1px solid #000;position:relative;z-index:2;overflow:hidden;cursor:move;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;" index="0" class="fullDiv">';
      html += '<div style="position:absolute;background:#ccc;top:0;z-index:4;opacity:0.95;left:0;right:0;margin:auto;" class="hideImgTop"></div>';
      html += '<div style="position:absolute;background:#ccc;bottom:0;z-index:4;opacity:0.95;left:0;right:0;margin:auto;" class="hideImgBottom"></div>';
      html += '<div style="position:absolute;height:100%;background:#ccc;left:0;z-index:4;opacity:0.95;" class="hideImgLeft"></div><div style="position:absolute;z-index:3;left:0;right:0;top:0;bottom:0;margin:auto;" class="cutDiv"></div>';
      html += '<div style="position:absolute;height:100%;background:#ccc;right:0;z-index:4;opacity:0.95;" class="hideImgRight"></div>';
      html += '<img style="position:absolute;z-index:1;width:'+showImgWidth+'px" onload="showCutImg(this)" class="cutImg" class="imgshover" src="'+objUrl+'" alt="图片加载失败" />';
      html += '</div>';          

      $(this).siblings('.showImgDiv').html(html);
    }

   }else{
    var objUrl = getObjectURL2($(this).get(0).files);
    if (objUrl) {

     var showImgWidth = $(this).siblings('.showImgDiv').attr('showImgWidth');

     if(!showImgWidth)
     {
      showImgWidth = '150';
     }

     var html = '';
     for(var i=0;i<objUrl.length;i++)
     {
      html += '<div style="margin-bottom:5px;border:1px solid #000;position:relative;z-index:2;overflow:hidden;cursor:move;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;" index="'+i+'" class="fullDiv">';
      html += '<div style="position:absolute;background:#ccc;top:0;z-index:4;opacity:0.95;left:0;right:0;margin:auto;" class="hideImgTop"></div>';
      html += '<div style="position:absolute;background:#ccc;bottom:0;z-index:4;opacity:0.95;left:0;right:0;margin:auto;" class="hideImgBottom"></div>';
      html += '<div style="position:absolute;height:100%;background:#ccc;left:0;z-index:4;opacity:0.95;" class="hideImgLeft"></div><div style="position:absolute;z-index:3;left:0;right:0;top:0;bottom:0;margin:auto;" class="cutDiv"></div>';
      html += '<div style="position:absolute;height:100%;background:#ccc;right:0;z-index:4;opacity:0.95;" class="hideImgRight"></div>';
      html += '<img style="position:absolute;z-index:1;width:'+showImgWidth+'px" onload="showCutImg(this)" class="cutImg" class="imgshover" src="'+objUrl[i]+'" alt="图片加载失败" />';
      html += '</div>';          //修改img标签的width样式可改变预览图大小

     }

     $(this).siblings('.showImgDiv').html(html);

    }

    //$('.fullDiv').css('float','left');
   }


  }) ;

  //建立一??可存取到?file的url
  function getObjectURL1(file) {
   var url = null ; 
   if (window.createObjectURL!=undefined) { // basic
    url = window.createObjectURL(file) ;
   } else if (window.URL!=undefined) { // mozilla(firefox)
    url = window.URL.createObjectURL(file) ;
   } else if (window.webkitURL!=undefined) { // webkit or chrome
    url = window.webkitURL.createObjectURL(file) ;
   }
   return url ;
  }

  //建立一??可存取到?file的url
  function getObjectURL2(file) {
   var url = new Array(); 
   if (window.createObjectURL!=undefined) { // basic
    for(var i=0;i<file.length;i++)
    {
     url[i] = window.createObjectURL(file[i]) ;
    }
   } else if (window.URL!=undefined) { // mozilla(firefox)
    for(var i=0;i<file.length;i++)
    {
     url[i] = window.URL.createObjectURL(file[i]) ;
    }
   } else if (window.webkitURL!=undefined) { // webkit or chrome
    for(var i=0;i<file.length;i++)
    {
     url[i] = window.webkitURL.createObjectURL(file[i]) ;
    }
   }
   return url ;
  }

html代码(这些代码要放在同一级)

<!-- 文件上传标签,添加class属性CutImage -->
<input class="CutImage" type="file" name="img" />

<!-- 传送图片裁剪比例等参数,要添加class属性imgCoord,ratio为裁剪后要保存的宽高width*height -->
<input ratio="100*100" type="hidden" class="imgCoord" name="imgCoord">

<!-- 图片预览,要添加class属性showImgDiv,showImgWidth表示预览时的宽度 -->
<div showImgWidth="100" class="showImgDiv"></div>

php代码

/*图片上传代码略 下面直接进行图片裁剪*/

/**
 * [cut_img 图片裁剪函数]
 * Author: 程威明
 * @param array $imgs   图片路径数组
 * @param array $info   裁剪信息?到M,包括裁剪后要保存的宽高、图片大小与裁剪开始坐标之比
 * @param bool $cover   是否覆盖原图,默认不覆盖
 * @return array    若覆盖原图返回裁剪数量,不覆盖返回图片路径组成的数组
 */
function cut_img($imgs=array(),$infoarr=null,$cover=false)
{
 if($infoarr==null) return $imgs;

 //判断是否为数组(必须是一个以图片路径组成的数组)
 $imgs = is_array($imgs)?$imgs:array($imgs);

 //把多个裁剪信息切成单个信息组成的数组
 $infoarr = explode(',', $infoarr);

 $save_file = array();

 $i=0;
 foreach($imgs as $file){

  //如果不覆盖原图,可重新定义图片保存路径
  if(false==$cover){
   $file = $file;
  }

  //把裁剪信息切割成数组,第一个为要保存的宽第二个为要保存的高,第三和第四个为图片宽高与裁剪起点的比例
  $info = explode('#', $infoarr[$i]);

  //裁剪宽高比
  $ratio = $info[0]/$info[1];

  //判断图片是否存在
  if(!file_exists($file)) continue;

  //获取图片信息
  $imgize = getimagesize($file);

  //图片宽度
  $width = $imgize[0];
  //图片高度
  $height = $imgize[1];

  //图片裁剪起点坐标
  $x = $info[2]==0?0:$imgize[0]/$info[2];
  $y = $info[3]==0?0:$imgize[1]/$info[3];

  //判断图片原宽高比与裁剪宽高比的大小
  if($width/$height>=$ratio){
   $width = $height*$ratio;//如大于即为裁剪宽度
  }else{
   $height = $width/$ratio;//如小于即为裁剪高度
  }

  //裁剪的??高不能超出?D片大小
  if(($width+$x)>$imgize[0]){
   $width = $width-($width+$x-$imgize[0]);
  }

  if(($height+$y)>$imgize[1]){
   $height = $height-($height+$y-$imgize[1]);
  }

  //创建源图的实例
  $src = imagecreatefromstring(file_get_contents($file));

  //??建一???D像
  $new_image = imagecreatetruecolor($info[0], $info[1]);

  //分配颜色
  $color = imagecolorallocate($new_image,255,255,255);
  //定义为透明色
  imagecolortransparent($new_image,$color);
  //填充图片
  imagefill($new_image,0,0,$color);

  //拷贝图片并保存成指定大小
  imagecopyresized($new_image, $src, 0, 0, $x, $y, $info[0], $info[1], $width, $height);

  //保存

  if(false==$cover){
   $file = rtrim(dirname($file),'/').'/c_'.basename($file);
   $save_file[] = $file;
  }

  imagejpeg($new_image,$file);

  imagedestroy($new_image);
  imagedestroy($src);

  $i++;
 }

 if(false==$cover){
  return $save_file;
 }else{
  return $i;
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

jQuery 相关文章推荐
jQuery.Form实现Ajax上传文件同时设置headers的方法
Jun 26 jQuery
jQuery上传插件webupload使用方法
Aug 01 jQuery
jQuery 实时保存页面动态添加的数据的示例
Aug 14 jQuery
简单实现jQuery手风琴效果
Aug 18 jQuery
jQuery 利用ztree实现树形表格的实例代码
Sep 27 jQuery
springmvc接收jquery提交的数组数据代码分享
Oct 28 jQuery
jQuery图片加载失败替换默认图片方法汇总
Nov 29 jQuery
通过jquery的ajax请求本地的json文件方法
Aug 08 jQuery
jQuery创建折叠式菜单
Jun 15 jQuery
jQuery zTree树插件的使用教程
Aug 16 jQuery
layui+jquery支持IE8的表格分页方法
Sep 28 jQuery
jQuery实现的图片点击放大缩小功能案例
Jan 02 jQuery
jQuery Ajax实现Select多级关联动态绑定数据的实例代码
Oct 26 #jQuery
jquery使用FormData实现异步上传文件
Oct 25 #jQuery
jQuery+Datatables实现表格批量删除功能【推荐】
Oct 24 #jQuery
jQuery pagination分页示例详解
Oct 23 #jQuery
jquery.pagination.js分页使用教程
Oct 23 #jQuery
jquery分页插件pagination使用教程
Oct 23 #jQuery
使用jquery Ajax实现上传附件功能
Oct 23 #jQuery
You might like
php利用cookie实现自动登录的方法
2014/12/10 PHP
PHP判断浏览器、判断语言代码分享
2015/03/05 PHP
phpMyAdmin安装并配置允许空密码登录
2015/07/04 PHP
Ubuntu彻底删除PHP7.0的方法
2018/07/27 PHP
用js怎么把&amp;字符换成&quot;&amp;amp:&quot;
2006/10/19 Javascript
JavaScript国旗变换效果代码
2008/08/13 Javascript
在JQuery dialog里的服务器控件 事件失效问题
2010/12/08 Javascript
js动态设置鼠标事件示例代码
2013/10/30 Javascript
老司机带你解读jQuery插件开发流程
2016/05/16 Javascript
Javascript 两种刷新方法以及区别和适用范围
2017/01/17 Javascript
完美解决手机浏览器顶部下拉出现网页源或刷新的问题
2017/11/30 Javascript
Vue中多个元素、组件的过渡及列表过渡的方法示例
2019/02/13 Javascript
在Chrome DevTools中调试JavaScript的实现
2020/04/07 Javascript
如何基于jQuery实现五角星评分
2020/09/02 jQuery
[01:06:07]2014 DOTA2国际邀请赛中国区预选赛5.21 DT VS CIS
2014/05/22 DOTA
[04:11]DOTA2亚洲邀请赛小组赛第一日 TOP10精彩集锦
2015/01/30 DOTA
[42:32]Secret vs Optic 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
python如何在列表、字典中筛选数据
2018/03/19 Python
Python 实现网页自动截图的示例讲解
2018/05/17 Python
解决Django数据库makemigrations有变化但是migrate时未变动问题
2018/05/30 Python
使用python itchat包爬取微信好友头像形成矩形头像集的方法
2019/02/21 Python
解决Jupyter因卸载重装导致的问题修复
2020/04/10 Python
Django DRF路由与扩展功能的实现
2020/06/03 Python
Python paramiko使用方法代码汇总
2020/11/20 Python
澳大利亚吉他在线:Artist Guitars
2017/03/30 全球购物
新秀丽官方旗舰店:Samsonite拉杆箱、双肩包、皮具
2018/03/05 全球购物
维多利亚的秘密官方网站:Victoria’s Secret
2018/10/24 全球购物
失业者真诚求职信范文
2013/12/25 职场文书
年度优秀员工获奖感言
2014/08/15 职场文书
幼儿园端午节活动方案
2014/08/25 职场文书
2014年司机工作总结
2014/11/21 职场文书
2015年派出所民警工作总结
2015/04/24 职场文书
毕业生入职感言
2015/07/31 职场文书
班主任工作总结范文
2015/08/13 职场文书
SQL实现LeetCode(180.连续的数字)
2021/08/04 MySQL
CentOS7安装GlusterFS集群以及相关配置
2022/04/12 Servers