jquery.imgareaselect是一款基于jquery,用于裁剪图片插件。将其集成到EXTJS的思路就是剥离jquery.imgareaselect提供的选择图片和上传功能,用将剩下的预览,裁剪定位数据嵌入到EXTJS中,实现起来还是比较简单的,具体代码如下:
首先是引入必需js和css文件。
<link rel="stylesheet" href="lib/imgareaselect/css/imgareaselect-default.css">
<script type="text/javascript" src="lib/jquery/jquery.js"></script>
<script type="text/javascript" src="lib/imgareaselect/js/jquery.imgareaselect.pack.js"></script>
<script type="text/javascript" src="lib/imgareaselect/js/preview.js"></script>
EXTJS代码如下
一个filefield组件作为裁剪的入口,文件也是基于它提交的。
{
xtype:'filefield',
margin: '10 5 10 10',//t r b l
itemId :'bannerImage',
id:'bannerImage',
name:'bannerImage',
fieldLabel:'活动标题图片',
columnWidth:.4,
allowBlank:false,
readOnly:true,
//文件类型验证 请根据自己的需求修改
validator: function(value){
if(value ==null||value == ""){
return
};
var me = this;
var arr = value.split('.');
if(arr[arr.length-1].toLowerCase() != 'jpg'.toLowerCase()
&&arr[arr.length-1].toLowerCase() != 'gif'.toLowerCase()
&&arr[arr.length-1].toLowerCase() != 'png'.toLowerCase()){
Ext.MessageBox.alert("错误","图片格式错误!");
return true;
}else {
return true;
}
},
listeners : {
//用户选择文件后触发
change : function (fileinfo){
//选择文件后打开自定义的裁剪窗口
var ImgareaselectWindow = Ext.create('Activity.ImgareaselectWindow');
ImgareaselectWindow.show();
//使用浏览器缓存实现图片的本地预览 url为浏览器缓存地址,并没有上传到服务器
var getObjectURL = function(file) {
var url = null;
if (window.createObjectURL != undefined) {
url = window.createObjectURL(file);
} else if (window.URL != undefined) {
url = window.URL.createObjectURL(file);
} else if (window.webkitURL != undefined) {
url = window.webkitURL.createObjectURL(file);
}
return url;
};
//组件input dom 全局变量 用于获取选中的图片和图片路径(虚拟路径)
mFileInputEl = fileinfo.fileInputEl.dom;
if (fileinfo.value) {
var msrc = getObjectURL(mFileInputEl.files[0]);
//为image组件设置图片路径
Ext.getCmp('previewImage').setSrc(msrc);
//根据image组件生成裁剪和预览对象,具体配置和参考jquery.imgareaselect文档 imgAreaSelectApi = $('#previewImage').imgAreaSelect( {aspectRatio: '1:1', handles:true, persistent:true,resizable:true,movable:true,instance:true, fadeSpeed:200, onSelectEnd:preview});
//显示默认选择状态
showDefaultSelect();
}
}
}
}
window组件用于裁剪和预览图片:
Ext.define('Activity.ImgareaselectWindow',{
extend:'Ext.window.Window',
width:500,
height:500,
getForm: function(){
var me = this;
if(me.form==null){
me.form = Ext.create('Ext.form.Panel',{
margin: '20 20 20 20',
border:false,
items:[{//image组件 用于预览
xtype : 'image',
border:true,
columnWidth:.9,
height :300,
style: {
width: '100%',
height:'100%',
},
id : 'previewImage',
src : Common.config.COVER_INIT_URL ,
listeners : {}
}]
});
}
return me.form;
},
initComponent: function() {
var me = this;
Ext.applyIf(me, {
items: [me.getForm()]
});
me.buttons = [{
text:'确定',
handler:function(){
//确定者取消时关闭窗口,手动关闭imgareaselect的裁剪视图
imgAreaSelectApi.cancelSelection();
me.close();
}
},{
text:'取消',
handler:function(){
imgAreaSelectApi.cancelSelection();
me.close();
}
}]
me.callParent(arguments);
}
});
下面是在imgareaselect代码上做的一下小改动 详见参考代码注释
//组件input dom 全局变量
var mFileInputEl,
//裁剪数据变量,原来的imgareaselect是用表单的方式保存这些数据,现在我们用EXTJS需要保存到变量中,在提交时在参数中加入这些变量和图片一并提交到后台
areaselect_fileSize,
areaselect_imgscale,
areaselect_beginX,
areaselect_beginY,
areaselect_cutWidth,
areaselect_cutHeight,
areaselect_sourceWidth,
areaselect_sourceHeight ;
//加载时触发的默认选区
function showDefaultSelect(){
debugger
//获取 x、y、w、h的值
var left = 80;
var top = 0;
var width = 200;
var height = 200;
var imgActualWidth, imgActualHeight;
var img = new Image();
img.src = document.getElementById('previewImage').src;
img.onload = function (){
imgActualWidth = img.width;
imgActualHeight = img.height;
var scale = 360/imgActualWidth;
top = (imgActualHeight*scale-200)/2;
//imgAreaSelectApi 就是图像img_origin的实例 上边instance已解释
//setSelection(),设置选区的坐标
//update(),更新
imgAreaSelectApi.setSelection(left, top, left+width, top+height,true);
imgAreaSelectApi.setOptions({ show: true });
imgAreaSelectApi.update();
var file = mFileInputEl.files[0];
areaselect_fileSize = file.size;
areaselect_imgscale = imgActualWidth/360;
areaselect_beginX = Math.round(left*areaselect_imgscale);
areaselect_beginY = Math.round(top*areaselect_imgscale);
areaselect_cutWidth = Math.round(width*areaselect_imgscale);
areaselect_cutHeight = Math.round(height*areaselect_imgscale);
areaselect_sourceWidth = Math.round(imgActualWidth);
areaselect_sourceHeight = Math.round(imgActualHeight);
}
} ;
// 如果加上aspectRatio: '1:1',$('#previewImage').imgAreaSelect( {aspectRatio: '1:1',handles:true, fadeSpeed:200, onSelectEnd : preview});则选取区域固定为正方形。
function preview(img, selection)
{
debugger
if(!selection.width || !selection.height)
return;
var file = mFileInputEl.files[0];
fileSize = file.size;
var imgActualWidth, imgActualHeight;
var img = new Image();
img.src = document.getElementById('previewImage').src;
img.onload = function (){
imgActualWidth = img.width;
imgActualHeight = img.height;
var scale = imgActualWidth/360;
areaselect_fileSize = file.size,
areaselect_imgscale = imgActualWidth/360,
areaselect_beginX = Math.round(selection.x1*areaselect_imgscale);
areaselect_beginY = Math.round(selection.y1*areaselect_imgscale);
areaselect_cutWidth = Math.round(selection.width*areaselect_imgscale);
areaselect_cutHeight = Math.round(selection.height*areaselect_imgscale);
areaselect_sourceWidth = Math.round(imgActualWidth);
areaselect_sourceHeight = Math.round(imgActualHeight);
}
}
前台代码就是这些,下面是后台
我的后台是由java实现的后台代码非常简单,根据imgareaselect提供的裁剪工具类和前台传递的图片和裁剪数据进行裁剪,获取新的图片并保存即可。
bannerImage = PictureCutUtil.cut(bannerImage, areaselect_cutWidth, areaselect_cutHeight, areaselect_beginX, areaselect_beginY, areaselect_sourceWidth, areaselect_sourceHeight);