所有分类
  • 所有分类
  • 后端开发
前端图片处理新选择:HTML5 API 崛起,取代衰落的 Flash

前端图片处理新选择:HTML5 API 崛起,取代衰落的 Flash

这里面有几个功能,第一个是支持拖拽,第二个压缩,第三个是裁剪编辑,第四个是上传和上传进度显示,下面依次介绍每个功能的实现:裁剪图片,上网找到了一个插件cropper,这个插件还是挺强大,支持裁剪、旋转、翻转,但是它并没有对图片真正的处理,只

网页要处理文件,先得让用户把文件丢过来,也就是拖拽读取。听着很高大上?其实只要监听网页里的”dragover”和”drop”这类拖拽事件就行了。等用户把文件拖到指定地方,程序就能抓住这个动作,再用FileReader这个小帮手读出文件内容。FileReader还有个神奇的功能,能把文件内容变成base64格式,这样就能直接在网页上看图了。不过,如果图片太大,转换时可能会有点慢,这时可以试试用webworker来帮忙,虽然它没法直接操作DOM,但能分担主进程的压力。

前端图片处理新选择:HTML5 API 崛起,取代衰落的 Flash

拖进来一个文档,咱们就把它抓住,接着用FileReader来拉出来看看。不过,有时候你要是拖进来一个大文件,可能觉得网页有点儿慢,那就是因为要把它转成base64得花点儿功夫。别急,咱们可以找webworker来帮帮忙,虽然它没法直接碰DOM,但是能让主进程轻松些。

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);
        });
     }
}

压缩图片

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

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

拖拽个大图片进来后,如果图片太大的话,那咱们就得给它减肥瘦身。这时候,咱们的canvas神器就能大显神通了!Canvas这货可是个牛逼哄哄的东西,让你在网站上随心所欲地涂鸦,还能帮咱处理图片。压缩图片的道理说白了,就是把一张大图塞进一个小小的画布里,然后再把这个小画布的内容变成base64格式,这样一来,一张缩水版的图片就诞生。这个过程既省时又有效,还能保证图片不变形。

readImgFile:function(file,$img,$container){
    varreader=newFileReader(file);
    //检验用户是否选则是图片文件
    if(file.type.split("/")[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);
}

压缩图片的事儿,咱们拿Canvas来搞定!先搞个比原图小点的画布,然后把原图搬进去,就成了压缩好的图片。这招儿速度快,效果也好,能让图片不变形地缩小。更棒的是,还能顺便解决一些别的图片问题,比如说旋转什么的。

裁剪图片

//获取图片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);

把图片弄小后,如果还要剪裁图片怎么办?咱们还是得靠Canvas。不过剪裁这活儿可是有点麻烦,得记住用户做的每一步,然后再根据这些步骤去微调图片。这时候,有个叫Cropper的神器就派上用场!它不仅能剪裁,还能旋转和翻转。但别忘了,它只负责记录你的操作,真正的处理工作还得靠咱们自己完成。

前端图片处理新选择:HTML5 API 崛起,取代衰落的 Flash

是的你没猜错,剪图这个事儿有点小复杂!咱们得先记录下用户怎么点点点的,然后依据这些动作来调整图片大小。比如说,咱可以先搞个跟图片一样大的画布,把原图直接复制过来,接着把选中的那部分用imageData给保存下来,然后把画布的大小也改成选中框那么大,再把imageData放回去,最后导出来就搞定!

readImgFile:function(file,$img,$container){
    EXIF.getData(file,function(){
        varorientation=this.exifdata.Orientation,
            rotateDeg=0;
        //如果不是ios拍的照片或者是横拍的,则不用处理,直接读取
        if(typeoforientation==="undefined"||orientation===1){
            //原本的readImgFile,添加一个rotateDeg的参数
            handler.doReadImgFile(file,$img,$container,rotateDeg);
        }  
        //否则用canvas旋转一下
        else{
            rotateDeg=orientation===6?90*Math.PI/180:
                            orientation===8?-90*Math.PI/180:
                            orientation===3?180*Math.PI/180:0;
            handler.doReadImgFile(file,$img,$container,rotateDeg);
        }  
    });
}

上传文件和显示上传进度

搞定图片后,就轮到上传!上传可简单了,像填表格或用ajax就能把文件传上服务器。在此期间,咱们还能给用户实时显示上传进度,让他们知道文件在哪儿,挺贴心的?这功能能让他们知道文件正在处理,还有多久才能上传结束。

//设定图片最大压缩宽度为1500px
varmaxWidth=1500;
varresultImg=handler.compress($img[0],maxWidth,file.type);

而且,这个功能还可以增加用户体验,让用户感觉网站很专业。

compress:function(img,maxWidth,mimeType){
    //创建一个canvas对象
    varcvs=document.createElement('canvas');
    varwidth=img.naturalWidth,
        height=img.naturalHeight,
        imgRatio=width/height;
    //如果图片维度超过了给定的maxWidth 1500,
    //为了保持图片宽高比,计算画布的大小
    if(width>maxWidth){
        width=maxWidth;
        height=width/imgRatio;
    }  
    cvs.width=width;
    cvs.height=height;
}

兼容性问题

    //把大图片画到一个小画布
    varctx=cvs.getContext("2d").drawImage(img,0,0,img.naturalWidth,img.naturalHeight,0,0,width,height);
    //图片质量进行适当压缩
    varquality=width>=1500?0.5:
                    width>600?0.6:1;
    //导出图片为base64
    varnewImageData=cvs.toDataURL(mimeType,quality);
 
    varresultImg=newImage();
    resultImg.src=newImageData;
    returnresultImg;

最后,别忘了考虑兼容性的事儿!每个浏览器都有自己的“喜好”,有的支持某些技术多些,有的就少些。比如说,大家知道吗?FileReader这玩意儿在IE10及以后版本的浏览器里才能用,所以,为了让咱们的代码在各种浏览器上都能用得溜,我们得保证它在IE10及其以上版本的浏览器上也能跑起来。虽然微软已经不再管IE11以下的浏览器了,但是,毕竟还有那么多人在用,所以,兼容性问题还是不能忽视滴。

兼容性的事真的让人头疼,各种浏览器对前端技术的支持都参差不齐,所以咱们得保证代码在各种浏览器下都能跑起来。

varctx=cvs.getContext("2d");
vardestX=0,
    destY=0;
if(rotateDeg){
    ctx.translate(cvs.width/2,cvs.height/2);
    ctx.rotate(rotateDeg);
    destX=-width/2,
    destY=-height/2;
}
ctx.drawImage(img,0,0,img.naturalWidth,img.naturalHeight,destX,destY,width,height);

原文链接:https://www.icz.com/technicalinformation/web/2024/07/19313.html,转载请注明出处~~~
0

评论0

请先
注意:请收藏好网址www.icz.com,防止失联!站内免费资源持续上传中…!赞助我们
显示验证码
没有账号?注册  忘记密码?