最近写了个,图像裁剪的插件,在这里稍微总结一下:
前端代码(样式可以自己调):
<div id="fileView" class="fileView"> <div class="imageBox hidden"> <div class="thumbBox"></div> <div class="spinner" style="display: none">Loading...</div> </div> <div class="imgDo"> <p><input type="button" class="hidden" id="btnZoomOut" value="-" style="margin-left:33px;width:20px;float: left"> <input type="button" class="hidden" id="btnZoomIn" value="+" style="margin-left:10px;width:20px;float: left"><a href="javascript:void(0)" id="btnCrop" class="btn3 btnsF14 hidden" style="margin-top:10px;">裁剪</a></p> <b class="hidden" id="yulan">预览:</b> <div id="preBox"> <img src='' id='prePic'> <a href="javascript:void(0);" id="imgDo">头像裁剪</a> </div> </div>
//之后调动了几个函数:
prePic();//显示预览
imgLode();//加载原图
sendPic();//发送截图数据
cropbox.js
"use strict"; (function (factory) { if (typeof define === 'function' && define.amd) { define(['jquery'], factory); } else { factory(jQuery); } }(function ($) { var cropbox = function(options, el){ var el = el || $(options.imageBox), obj = { state : {}, ratio : 1, options : options, imageBox : el, thumbBox : el.find(options.thumbBox), spinner : el.find(options.spinner), image : new Image(), getDataURL: function () { var width = this.thumbBox.width(), height = this.thumbBox.height(), canvas = document.createElement("canvas"), dim = el.css('background-position').split(' '), size = el.css('background-size').split(' '), dx = parseInt(dim[0]) - el.width()/2 + width/2,//截图位置 dy = parseInt(dim[1]) - el.height()/2 + height/2, dw = parseInt(size[0]),//缩放大小 dh = parseInt(size[1]), sh = parseInt(this.image.height),//原图宽 sw = parseInt(this.image.width);//原图高 // canvas.width = width; (由于要处理的图片,已经保存到了服务器,用户不能直接用canvas,这里存在一个,域的问题) // canvas.height = height; // var context = canvas.getContext("2d"); //context.drawImage(this.image, 0, 0, sw, sh, dx, dy, dw, dh); //var imageData = canvas.toDataURL('image/png'); var data = {sw:sw,sh:sh,dx:dx,dy:dy,dw:dw,dh:dh}; return data; }, getBlob: function() { var imageData = this.getDataURL(); var b64 = imageData.replace('data:image/png;base64,',''); var binary = atob(b64); var array = []; for (var i = 0; i < binary.length; i++) { array.push(binary.charCodeAt(i)); } return new Blob([new Uint8Array(array)], {type: 'image/png'}); }, zoomIn: function () { this.ratio*=1.1; setBackground(); }, zoomOut: function () { this.ratio*=0.9; setBackground(); } }, setBackground = function() { var w = parseInt(obj.image.width)*obj.ratio; var h = parseInt(obj.image.height)*obj.ratio; var pw = (el.width() - w) / 2; var ph = (el.height() - h) / 2; el.css({ 'background-image': 'url(' + obj.image.src + ')', 'background-size': w +'px ' + h + 'px', 'background-position': pw + 'px ' + ph + 'px', 'background-repeat': 'no-repeat'}); }, imgMouseDown = function(e) { e.stopImmediatePropagation(); obj.state.dragable = true; obj.state.mouseX = e.clientX; obj.state.mouseY = e.clientY; }, imgMouseMove = function(e) { e.stopImmediatePropagation(); if (obj.state.dragable) { var x = e.clientX - obj.state.mouseX; var y = e.clientY - obj.state.mouseY; var bg = el.css('background-position').split(' '); var bgX = x + parseInt(bg[0]); var bgY = y + parseInt(bg[1]); el.css('background-position', bgX +'px ' + bgY + 'px'); obj.state.mouseX = e.clientX; obj.state.mouseY = e.clientY; } }, imgMouseUp = function(e) { e.stopImmediatePropagation(); obj.state.dragable = false; }, zoomImage = function(e) { e.originalEvent.wheelDelta > 0 || e.originalEvent.detail < 0 ? obj.ratio*=1.1 : obj.ratio*=0.9; setBackground(); } obj.spinner.show(); obj.image.onload = function() { obj.spinner.hide(); setBackground(); el.bind('mousedown', imgMouseDown); el.bind('mousemove', imgMouseMove); $(window).bind('mouseup', imgMouseUp); el.bind('mousewheel DOMMouseScroll', zoomImage); }; obj.image.src = options.imgSrc; el.on('remove', function(){$(window).unbind('mouseup', imgMouseUp)}); return obj; }; jQuery.fn.cropbox = function(options){ return new cropbox(options, this); }; }));
这里操作后,获得了几个参数(url,dx, dy, dw, dh),发送到服务器端。
php在进一步处理:
/*
*参数分别对应dx, dy, dw, dh
*/
function imagecropper($source_path, $source_x,$source_y,$target_width, $target_height) { $cropped_width = 122;//规定截图宽度为122 $cropped_height = 152;//规定截图高度为152 $source_info = getimagesize($source_path); $source_width = $source_info[0]; $source_height = $source_info[1]; $source_mime = $source_info['mime']; if($target_width<$cropped_width || $target_height< $cropped_height){//如果截图太小,选择原图,并放大到规定大小。 $target_width = $cropped_width; $target_height = $cropped_height; $source_x = 0; $source_y = 0; } $temp = dirname(SITE_PATH).'/img/tmp/'.time(); switch ($source_mime) { case 'image/gif': $source_image = imagecreatefromgif($source_path); $_type = '.gif'; $temp .=$_type; break; case 'image/jpeg': $source_image = imagecreatefromjpeg($source_path); $_type = '.jpg'; $temp .=$_type; break; case 'image/png': $source_image = imagecreatefrompng($source_path); $_type ='.png'; $temp .=$_type; break; default: return false; break; } $target_image = imagecreatetruecolor($target_width, $target_height);//创建了放大图片的画布 $cropped_image = imagecreatetruecolor($cropped_width, $cropped_height);//创建截图后的画布 imagecopyresampled($target_image,$source_image,0,0,0,0,$target_width,$target_height,$source_width,$source_height);//缩放图片 $source_x = abs($source_x); $source_y = abs($source_y); imagecopy($cropped_image, $target_image, 0, 0, $source_x, $source_y, $cropped_width,$cropped_height);//切割 header('Content-Type: image/jpeg'); imagejpeg($cropped_image,$temp); imagedestroy($source_image); imagedestroy($target_image); imagedestroy($cropped_image); //$upyun = new \func\upyunFunc;//这里调用了upyun,可省略掉 //$upyun->setup(); //$picUrl = $upyun->DirectUpload($temp,$_type,1); /*if($picUrl){ $del_path = substr($source_path,20); $upyun->Delete($del_path); }*/ return $picUrl; }