最近因为工作需要,做了视频截图和图截图的功能。大概需求是,用户点击某个按钮,可以对图片区域进行部分截取,然后进行进一步的业务操作。
首先说图片截图功能的思路,
(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)。