最近因为工作需要,做了视频截图和图截图的功能。大概需求是,用户点击某个按钮,可以对图片区域进行部分截取,然后进行进一步的业务操作。
首先说图片截图功能的思路,
(1)下载Jcrop插件,添加css和js的依赖到自己的项目,这么简单的东西,我就不手把手教了。
(2)Jcrop提供的功能很多,我用到的只是获取到截图后的矩形区域的四个点坐标,即相对了图片左上角的偏移量,单位为px。
(3)通过四个点的偏移量,裁剪图片此处有两种方法,一是到后台获取原图片的信息,利用后台语音进行裁剪,本人从事Java开发,所以用的是Java。
还有一种是利用canvas的drawImage函数以及toDataURL函数,在前端获去截取的图片base64字符串。得到截图图片。
(4)注意事项,canvas的toDataURL函数,有跨域限制,也就是跨域的话,浏览器会报错。解决方法,后面会给出。
直接贴代码吧
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@page import="java.util.Map"%> <html> <head> <title>Insert title here</title> <link rel="stylesheet" href="<%=request.getContextPath() %>/css/jquery.Jcrop.min.css"> <script type="text/javascript" src="<%=request.getContextPath() %>/js/jquery-3.1.1.min.js"></script> <script type="text/javascript" src="<%=request.getContextPath() %>/js/jquery.Jcrop.min.js"></script> <script type="text/javascript"> var jcrop = null; function initJscop(){ $('#cutImg').Jcrop({ onChange : onChange, allowResize : true },function(){ jcrop = this; }); } function onChange(e){ $('#x1').val(e.x); $('#x2').val(e.x2); $('#y1').val(e.y); $('#y2').val(e.y2); } function goCut(){ jcrop.release(); var x1 = $('#x1').val(); var x2 = $('#x2').val(); var y1 = $('#y1').val(); var y2 = $('#y2').val(); var imgs =document.getElementById("cutImg"); var cavs = document.getElementById("cavs"); var ctx = cavs.getContext('2d'); var w = x2 - x1; var h = y2 - y1; ctx.drawImage(imgs,x1,y1,w,h,0,0,w,h); var url = ctx.canvas.toDataURL(); } window.onload = function(){ initJscop(); }; </script> </head> <body> <input type="hidden" id="x1"> <input type="hidden" id="x2"> <input type="hidden" id="y1"> <input type="hidden" id="y2"> <img alt="" id="cutImg" src="<%=request.getContextPath() %>/images/pool.jpg"> <canvas id="cavs" width="500px;" height="370px;"></canvas> <button onclick="goCut();">CUT</button> </body> </html>
jcrop 对象可以操作对应的截图事件,在页面加载的时候,初始化它,当然初始化的时机不一定和我一样。
onChange : onChange,代表截图过程的事件,传入参数e可以获取到对应的矩形区域的四个偏移量。
jcrop.release() 代表取消绘制事件,重新绘制。
ctx.drawImage(imgs,x1,y1,w,h,0,0,w,h);这个方法需要着重描述,api如图所示
原网页链接:http://www.runoob.com/tags/canvas-drawimage.html
ctx.drawImage(imgs,x1,y1,w,h,0,0,w,h)返回裁剪图片的base64位字符串。至此,就可以完成图片或者视频的截图功能了。
but,这一切都是在图片和视频都在你的web服务下,才行的通,然鹅,在开发中,图片可能不是来自己的项目,视频服务,也可以能是另外搭建的。
这种情况下,调用方法
ctx.drawImage(imgs,x1,y1,w,h,0,0,w,h)浏览器会抛出异常,也得不到base64的字符串。
针对图片的截图,解决这个问题的方式有两个
首先在img标签或者video标签设置属性
crossOrigin = "Anonymous",建议动态设置,本人写死在标签,会出现视频无法播放的问题。估计是知识研究的不够透彻
(1)在图片提供图片服务的响应头添加Access-Control-Allow-Origin *
(2)根据图片url,在后台将对应的图片转成base64,再将base64的图片展示在前端,在此基础上进行截图操作,这样就不存在同源策略的问题了。
针对视频,虽然(1)、(2)都适用,但是视频转base64的字符串过长,并不建议用这种方式,所以对于视频的截图,我推荐的解决方法是(1)。