一个利用html5的图片裁剪功能(已解决ios压扁缩放等bug)

前言:

手机越来越普遍,利用手机即时拍照裁剪图片的功能需求是存在的。不才目前供职于一家网站,里面也有触屏版需要裁剪图片。

技术难点:

一般难点:

html5对图片的读取处理。

意外难点:

难点1、ios6,7下面对超过2M的图片有一个限制,该限制使得假如你直接将2m的本地图片或者相片绘制到canvas画布上面会出现压扁现象。

难点2、ios拍照会有额外的exif信息(图片信息),该信息包含了拍摄日期,作者,还有一个很关键的orientation(角度),ios拍摄有四个角度,分别为1,3,6,8,里面的代表含义记不清楚,不过就是表示,正拍,左旋90度,右旋90度,旋转180度。由于ios有这个orientation,所以假如用户使用ios的其他角度拍摄,直接绘制到画布上面会出现图片颠倒,并非用户希望的情形。这时候你就要根据角度进行调整了。

三、部分代码,为何这是部分代码?因为涉及到前端后端及样式,我没法提供完整代码,而且,涉及到公司机密,我只能提供一些我在解决bug途中所写的测试代码。

譬如,将图片颠倒缩小在放大,用于用户拖动裁剪框以后,js获得用户拖动的坐标,高度宽度,再根据相片的orientation逆推原本的坐标及正确的高度宽度,,然后裁剪出那一部分图像,再根据orientation调整角度,必要时需要颠倒,缩放图像。

<html><head><title>画布的旋转、缩放等功能。</title><script type="text/javascript" src="/static/mobile/lib/zepto.min.js"></script></head><body><h1>选择:<a href="javascript:changeImg(6);">右旋90度图片</a> <a href="javascript:changeImg(3);">旋转180度图片</a> <a href="javascript:changeImg(8);">左旋90度图片</a> <a href="javascript:changeImg(1);">正常图片</a></h1><img id="sourceImg" src="images/exif_info_6.jpg" style="max-width: 400px;max-height: 400px;"/><fieldset><legend>设置需要裁剪的x,y,及裁剪高度及宽度。</legend><div><table><tr><td>x:</td><td><input type="text" id="txt_x" value="600"/></td></tr><tr><td>y:</td><td><input type="text" id="txt_y" value="800"/></td></tr><tr><td>width:</td><td><input type="text" id="txt_width" value="1480"/></td></tr><tr><td>height:</td><td><input type="text" id="txt_height" value="850"/></td></tr><tr><td>Orientation:</td><td><input type="text" id="txt_Orientation" value="6"/></td></tr><tr><td>画布缩小倍数:</td><td><input type="text" id="txt_scale" value="5"/></td></tr><tr><td> </td><td><input type="button" value="裁剪到临时画布" id="btn_saveToTmp"></td></tr></table></div><div>临时画布:</div><div style="border: 1px green solid;"><canvas id="canvas_tmp"></canvas></div><div>最终画布</div><div style="border: 1px red solid;"><canvas id="canvas_final"></canvas><div id="results"></div></div></fieldset></body></html><script type="text/javascript">function changeImg(_Orientation){switch (_Orientation){case 8:setX(750);setY(220);setW(1800);setH(1200);setScale(5); setOrientation(8);_sourceImg.src="images/exif_info_8.jpg";break;case 6:setX(600);setY(800);setW(1480);setH(850);setScale(5); setOrientation(6);_sourceImg.src="images/exif_info_6.jpg";break;case 3:setX(600);setY(450);setW(2300);setH(1450);setScale(5);setOrientation(3);_sourceImg.src="images/exif_info_3.jpg";break;case 1:setX(600);setY(450);setW(2300);setH(1450);setScale(5);setOrientation(1);_sourceImg.src="images/exif_info_1.jpg";break;}}var _sourceImg=document.getElementById("sourceImg");var tmpCanvas=document.getElementById("canvas_tmp");var tmpContext=tmpCanvas.getContext("2d");var finalCanvas=document.getElementById("canvas_final");var finalContext=finalCanvas.getContext("2d");function getX(){return parseInt($("#txt_x").val());}function getY(){return parseInt($("#txt_y").val());}function getW(){return parseInt($("#txt_width").val());}function getH(){return parseInt($("#txt_height").val());}function getScale(){return parseFloat($("#txt_scale").val());}function getOrientatin(){return parseFloat($("#txt_Orientation").val());}function setX(x){$("#txt_x").val(x);}function setY(x){$("#txt_y").val(x);}function setW(x){$("#txt_width").val(x);}function setH(x){$("#txt_height").val(x);}function setScale(x){$("#txt_scale").val(x);}function setOrientation(x){$("#txt_Orientation").val(x);}function drawToTmpCanvas(x,y,w,h){tmpContext.clearRect(0,0,tmpCanvas.width,tmpCanvas.height) ;var _cW=parseFloat(w/getScale());var _cH=parseFloat(h/getScale());tmpCanvas.width=_cW;tmpCanvas.height=_cH;tmpContext.drawImage(_sourceImg,x,y,w,h,0,0,_cW,_cH);}$("#btn_saveToTmp").click(function(){drawToTmpCanvas(getX(),getY(),getW(),getH());var _cW=parseFloat(getW()/getScale());var _cH=parseFloat(getH()/getScale());$("#results").html("");var newCanvas=document.createElement("canvas");var newContext=newCanvas.getContext("2d");$("#results").append(newCanvas);drawToFinal(tmpCanvas,newCanvas,newContext,_cW,_cH,getOrientatin());});function drawToFinal(_sourceCanvas,_drawCanvas,_drawContext,_sw,_sh,_Orientation){switch(_Orientation){case 8:// 90 rotate left–需要90度向左旋转。。那么,这个 PixelYDimension就是宽度了,PixelXDimension就是高度了。_drawCanvas.width=_sh;_drawCanvas.height=_sw;var tSetting={dx:0,dy:0,dw:0,dh:0,transX:0,transY:0};tSetting.dw=_sh;var scale2=_sw/_sh;tSetting.dh=parseFloat(tSetting.dw/scale2);tSetting.dy=(_sw-tSetting.dh)/2;tSetting.transY=_sw/2;tSetting.transX=_sh/2;_drawContext.translate(tSetting.transX,tSetting.transY);_drawContext.rotate(-0.5*Math.PI);_drawContext.scale(scale2,scale2);_drawContext.drawImage(_sourceCanvas,0,0,_sw,_sh,tSetting.dx-tSetting.transX,tSetting.dy-tSetting.transY,tSetting.dw,tSetting.dh);break;case 3://180向左旋转 (右旋转也可以。)_drawCanvas.width=_sw;_drawCanvas.height=_sh;var tSetting={dx:0,dy:0,dw:0,dh:0,transX:0,transY:0};tSetting.dw=_sw;tSetting.dh=_sh;tSetting.transY=_sh/2;tSetting.transX=_sw/2;_drawContext.translate(tSetting.transX,tSetting.transY);_drawContext.rotate(1*Math.PI);//_drawContext.scale(scale2,scale2);_drawContext.drawImage(_sourceCanvas,0,0,_sw,_sh,tSetting.dx-tSetting.transX,tSetting.dy-tSetting.transY,tSetting.dw,tSetting.dh);break;case 6://90 rotate right 需要向右旋转90度,PixelYDimension就是宽度了,PixelXDimension就是高度了。_drawCanvas.width=_sh;_drawCanvas.height=_sw;var tSetting={dx:0,dy:0,dw:0,dh:0,transX:0,transY:0};tSetting.dw=_sh;var scale2=_sw/_sh;tSetting.dh=parseFloat(tSetting.dw/scale2);tSetting.dy=(_sw-tSetting.dh)/2;tSetting.transY=_sw/2;tSetting.transX=_sh/2;_drawContext.translate(tSetting.transX,tSetting.transY);_drawContext.rotate(0.5*Math.PI);_drawContext.scale(scale2,scale2);_drawContext.drawImage(_sourceCanvas,0,0,_sw,_sh,tSetting.dx-tSetting.transX,tSetting.dy-tSetting.transY,tSetting.dw,tSetting.dh);break;case 1://正常状态。_drawCanvas.width=_sw;_drawCanvas.height=_sh;var tSetting={dx:0,dy:0,dw:0,dh:0,transX:0,transY:0};tSetting.dw=_sw;tSetting.dh=_sh;tSetting.transY=_sh/2;tSetting.transX=_sw/2;_drawContext.translate(tSetting.transX,tSetting.transY);//_drawContext.rotate(1*Math.PI);//_drawContext.scale(scale2,scale2);_drawContext.drawImage(_sourceCanvas,0,0,_sw,_sh,tSetting.dx-tSetting.transX,tSetting.dy-tSetting.transY,tSetting.dw,tSetting.dh);break;break;}}</script>

测试用结果如下:

只想到处流浪人生就像一场旅行,不必在乎目的地,

一个利用html5的图片裁剪功能(已解决ios压扁缩放等bug)

相关文章:

你感兴趣的文章:

标签云: