WEB前端实现裁剪上传图片功能

最后的效果如下:

WEB前端实现裁剪上传图片功能

这里面有几个功能,第一个是支持拖拽,第二个压缩,第三个是裁剪编辑,第四个是上传和上传进度显示,下面依次介绍每个功能的实现:

1. 拖拽显示图片

拖拽读取的功能主要是要兼听html5的drag事件,这个没什么好说的,查查api就知道怎么做了,主要在于怎么读取用户拖过来的图片并把它转成base64以在本地显示。

var handler = { init: function($container){ //需要把dragover的默认行为禁掉,不然会跳页 $container.on("dragover", function(event){ event.preventDefault(); }); $container.on("drop", function(event){ event.preventDefault(); //这里获取拖过来的图片文件,为一个File对象 var file = event.originalEvent.dataTransfer.files[0]; handler.handleDrop($(this), file); }); } } varhandler={ init:function($container){ //需要把dragover的默认行为禁掉,不然会跳页 $container.on("dragover",function(event){ event.preventDefault(); }); $container.on("drop",function(event){ event.preventDefault(); //这里获取拖过来的图片文件,为一个File对象 varfile=event.originalEvent.dataTransfer.files[0]; handler.handleDrop($(this),file); }); } }

代码第10行获取图片文件,然后传给11行处理。

如果使用input,则监听input的change事件:

$container.on("change", "input[type=file]", function(event){ if(!this.value) return; var file = this.files[0]; handler.handleDrop($(this).closest(".container"), file); this.value = ""; }); $container.on("change","input[type=file]",function(event){ if(!this.value)return; varfile=this.files[0]; handler.handleDrop($(this).closest(".container"),file); this.value=""; });

代码第3行,获取File对象,同样传给handleDrop进行处理

接下来在handleDrop函数里,读取file的内容,并把它转成base64的格式:

handleDrop: function($container, file){ var $img = $container.find("img"); handler.readImgFile(file, $img, $container); }, handleDrop:function($container,file){ var$img= $container.find("img"); handler.readImgFile(file,$img,$container); },

我的代码里面又调了个readImgFile的函数,helper的函数比较多,主要是为了拆解大模块和复用小模块。

在readImgFile里面读取图片文件内容:

使用FileReader读取文件 JavaScript

readImgFile: function(file, $img, $container){ var reader = new FileReader(file); //检验用户是否选则是图片文件 if(file.type.split("https://www.jb51.net/")[0] !== "image"){ util.toast("You should choose an image file"); return; } reader.onload = function(event) { var base64 = event.target.result; handler.compressAndUpload($img, base64, file, $container); } reader.readAsDataURL(file); } readImgFile:function(file,$img,$container){ varreader=newFileReader(file); //检验用户是否选则是图片文件 if(file.type.split("https://www.jb51.net/")[0]!=="image"){ util.toast("You should choose an image file"); return; } reader.onload=function(event){ varbase64=event.target.result; handler.compressAndUpload($img,base64,file, $container); } reader.readAsDataURL(file); }

这里是通过FileReader读取文件内容,调的是readAsDataURL,这个api能够把二进制图片内容转成base64的格式,读取完之后会触发onload事件,在onload里面进行显示和上传:

//获取图片base64内容 var base64 = event.target.result; //如果图片大于1MB,将body置半透明 if(file.size > ONE_MB){ $("body").css("opacity", 0.5); } //因为这里图片太大会被卡一下,整个页面会不可操作 $img.attr("src", baseUrl); //还原 if(file.size > ONE_MB){ $("body").css("opacity", 1); } //然后再调一个压缩和上传的函数 handler.compressAndUpload($img, file, $container); //获取图片base64内容 varbase64=event.target.result; //如果图片大于1MB,将body置半透明 if(file.size>ONE_MB){ $("body").css("opacity",0.5); } //因为这里图片太大会被卡一下,整个页面会不可操作 $img.attr("src",baseUrl); //还原 if(file.size>ONE_MB){ $("body").css("opacity",1); } //然后再调一个压缩和上传的函数 handler.compressAndUpload($img,file,$container);

如果图片有几个Mb的,在上面第8行展示的时候被卡一下,笔者曾尝试使用web worker多线程解决,但是由于多线程没有window对象,更不能操作dom,所以不能很好地解决这个问题。采取了一个补偿措施:通过把页面变虚告诉用户现在在处理之中,页面不可操作,稍等一会

这里还会有一个问题,就是ios系统拍摄的照片,如果不是横着拍的,展示出来的照片旋转角度会有问题,如下一张竖着拍的照片,读出来是这样的:

WEB前端实现裁剪上传图片功能


内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wzdzyy.html