用户上传头像然后截图的需求很常见,很多做法是把图像发送到后端,把裁剪后的结果发送给浏览器,这种方式会增加处理时延。最近正好学习了HTML5里的canvas,发现它的图片处理功能比较强大,就打算用canvas提供的API实现纯前端的剪切。这里头关键有三步:显示未经处理的图片,得到裁剪区域,显示裁剪后的区域。我们分别讨论:

1. 显示未经处理的图片

创建一个canvas,用drawImage(img,0,0,canvas.width,canvas.height)就可以。主要这里的img是一个Image类的object, 用new Image创建。

 var img = new Image();
img.src = "./beauty.jpg";
img.onload = function(){
cxt1.drawImage(img,,,canvas1.width,canvas1.height); //一定要写在onload回调中,否则看不到图片
}

设计坞https://www.wode007.com/sites/73738.html

2. 得到裁剪区域

        用一个position:absolute的div框来选择裁剪区域,通过javascript提供的方法能得到该div在canvas中所处的位置(x,y),然后用getImageData(srcX,srcY,width,height)得到选择框中的像素点。 这里需要知道,通过canvas.getBoundingClientRect().left和canvas.getBoundingClientRect().top可以得到canvas相对于浏览器视图的左边和上边位置。

3. 显示裁剪后的区域

       这部分是最复杂的。假设getImageData得到了imgData, 需要创建一个canvas2,用canvas2.putImageData(imgData,0,0,canvas2.width,canvas2.height)将选择框里的像素绘制到这个临时的canvas2里。然后用canvas2.toDataURL("image/png")将canvas2转为dataurl类型的图片。有了dataurl后,就可以正常显示裁剪后的图片了。
       那么问题来了。为什么不能直接把getImageData得到的imgData通过putImageData绘制到最终要显示的区域,而非要创建一个临时的canvas2(不再页面上显示)呢?其实这是我想出来的一个折中方案。用putImageData绘制的画布上,只能按照等比例或者更小比例显示imgData,如果你想把剪切出来的图片放大显示,putImageData是不能支持的(这个结论是我经过测试发现的)。所以为了看到放大后的剪切区域(即使牺牲清晰度),就要用drawImage方法了,而drawImage的第一个参数不能是一堆像素数据,就只能用一个临时的canvas来作为像素数据和dataurl之间的桥梁了。

最后,上一段测试代码(可运行):

 <!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.mark{
position:absolute;
height:100px;
width:100px;
left:100px;
top:180px;
border:1px solid #;
cursor:move;
}
</style>
</head>
<body>
<canvas id="c1"></canvas> //显示原图像
<div class="mark" id="mark"></div>
<canvas id="c3"></canvas> //显示剪切后的图像
<script>
var canvas1 = document.getElementById("c1")
var oMark = document.getElementById("mark")
var canvas3= document.getElementById("c3")
canvas1.height = ;
canvas1.width=;
canvas3.height=;
canvas3.width=;
var cxt1 = canvas1.getContext("2d")
var img = new Image();
img.src = "./beauty.jpg";
var srcX = oMark.offsetLeft-canvas1.getBoundingClientRect().left;
var srcY = oMark.offsetTop-canvas1.getBoundingClientRect().top;
var sWidth = oMark.offsetWidth;
var sHeight = oMark.offsetHeight; var canvas2 = document.createElement("canvas")
var cxt2=canvas2.getContext("2d")
img.onload = function(){
cxt1.drawImage(img,,,canvas1.width,canvas1.height);
var dataImg = cxt1.getImageData(srcX,srcY,sWidth,sHeight)
canvas2.width = sWidth;
canvas2.height = sHeight;
cxt2.putImageData(dataImg,,,,,canvas2.width,canvas2.height)
var img2 = canvas2.toDataURL("image/png"); var cxt3=canvas3.getContext("2d")
var img3 = new Image();
img3.src = img2;
img3.onload = function(){
cxt3.drawImage(img3,,,canvas3.width,canvas3.height)
}
}
</script>
</body>
</html>

web图片前端裁剪功能实现_利用html5 canvas技术实现图片裁剪的更多相关文章

  1. 基于HTML5 Canvas实现的图片马赛克模糊特效

    效果请点击下面网址: http://hovertree.com/texiao/html5/1.htm 一.开门见山受美国肖像画家Chuck Close的启发,此脚本通过使用HTML5 canvas元素 ...

  2. 利用html5 canvas实现纯前端上传图片的裁剪

    今天跟大家分享一个前端裁剪图片的方法.许多网站都有设置用户头像的功能,用户可以选择一张本地的图片,然后用网站的裁剪工具进行裁剪,然后设置大小,位置合适的头像.当然,网上也有一些用js写的诸如此类裁剪的 ...

  3. [js高手之路] html5 canvas系列教程 - 图片操作(drawImage,clip,createPattern)

    接着上文[js高手之路] html5 canvas系列教程 - 文本样式(strokeText,fillText,measureText,textAlign,textBaseline)继续,本文介绍的 ...

  4. HTML5 Canvas前台压缩图片并上传到服务器

    1.前台代码: <input id="fileOne" type="file" /> <input id="btnOne" ...

  5. 利用HTML5和css3 选中图片上传到服务器,插件地址如下

    https://yusi123.com/3349.html 分三步,需要将js文件和css文件拷贝到项目目录下,在需要选择的图片的文件中引入,然后将HTML代码复制 <!--选择图片模块star ...

  6. HTML5 Canvas显示本地图片实例1、Canvas预览图片实例1

    1.前台代码: <input id="fileOne" type="file" /> <canvas id="canvasOne&q ...

  7. [HTML5] Canvas绘制简单图片

    获取Image对象,new出来 定义Image对象的src属性,参数:图片路径 定义Image对象的onload方法,调用context对象的drawImage()方法,参数:Image对象,x坐标, ...

  8. 利用HTML5 Canvas和Javascript实现的蚁群算法求解TSP问题演示

    HTML5提供了Canvas对象,为画图应用提供了便利. Javascript可执行于浏览器中, 而不须要安装特定的编译器: 基于HTML5和Javascript语言, 可随时编写应用, 为算法測试带 ...

  9. 移动端 Web 开发前端知识整理

    文章来源: http://www.restran.net/2015/05/14/mobile-web-front-end-collections/ 最近整理的移动端 Web 开发前端知识,不定期更新. ...

随机推荐

  1. java实现取球博弈

    今盒子里有n个小球,A.B两人轮流从盒中取球,每个人都可以看到另一个人取了多少个,也可以看到盒中还剩下多少个,并且两人都很聪明,不会做出错误的判断. 我们约定: 每个人从盒子中取出的球的数目必须是:1 ...

  2. cocos2dx Android 使用ant 批量打包

    参考文章: 例子:http://www.2cto.com/kf/201305/208139.html http://blog.csdn.net/ljb_blog/article/details/127 ...

  3. Php-webdriver 的安装与使用教程

    Php-webdriver 是 Facebook 开发的基于 PHP 语言实现的 Selenium WebDriver 客户端组件,可以用它来操作浏览器.常见的操作包括:自动化测试.采集数据等. 安装 ...

  4. KVM虚拟机使用NAT+iptables做端口映射

    环境介绍 有一个KVM宿主机,一个外网IP绑定在了宿主服务器上,但是希望直接用ssh访问上面的所有虚拟机,还想虚拟机提供外网服务, 解决方法如下: 环境为RHEL6.3,外网IP为 61.155.xx ...

  5. 自己动手实现深度学习框架-7 RNN层--GRU, LSTM

    目标         这个阶段会给cute-dl添加循环层,使之能够支持RNN--循环神经网络. 具体目标包括: 添加激活函数sigmoid, tanh. 添加GRU(Gate Recurrent U ...

  6. k8s学习-安全

    4.8.安全 4.8.1.概念 一些内容可参考4.6.2.Secret的内容 说明 Kubernetes 作为一个分布式集群的管理工具,保证集群的安全性是其一个重要的任务.API Server 是集群 ...

  7. boost常用库(一):boost数值转换

    在STL中有一些字符转换函数,例如atoi,itoa等,在boost里面只需用一个函数lexical_cast进行转换,lexical_cast是模板方法,使用时需要传入类型.只能是数值类型转字符串. ...

  8. nginx下如何l在网站目录的二级目录下url重写的方法

    以我新项目为例子,该项目要求用laravel来做,因此我把整个项目丢到一个叫laravel的文件夹里面了,目录就变成c:/nginx/html/laravel了,然后发现只能通过localhost/l ...

  9. TensorFlow从0到1之TensorBoard可视化数据流图(8)

    TensorFlow 使用 TensorBoard 来提供计算图形的图形图像.这使得理解.调试和优化复杂的神经网络程序变得很方便.TensorBoard 也可以提供有关网络执行的量化指标.它读取 Te ...

  10. cb38a_c++_STL_算法_transform

    cb38a_c++_STL_算法_transformtransform()算法有两种形式:transform(b1,e1,b2,op);//b1(源区间)的数据通过op函数处理,存放在b2(目标区间) ...