对Html标签截图代码(直接引入html2canvas.js文件)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.bootcss.com/html2canvas/0.5.0-beta4/html2canvas.js"></script>
</head>
<body>
<div id="capture" style="background: coral">
<h2>this is
<b>bold</b>
<span style="color:red">red</span>
</h2>
</div>
<input type="button" value="生成" onclick="goFun()" />
</body>
<script type="text/javascript">
function goFun(){
setTimeout(function(){
html2canvas(document.querySelector("#capture")).then(canvas => {
document.body.appendChild(canvas)
});
},1500)
}
</script>
</html>
特殊的对viedo标签进行截图(注意修改下面的source 标签的视频路径为本地的):
注意:如果使用drawImage截取标签浏览器会报错:Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(CSSImageValue or HTMLImageElement or SVGImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap or OffscreenCanvas)'
大概的意思是:未捕获的类型错误:未能在“CanvasRenderingContext2D”上执行“drawImage”:提供的值不是类型“(CSSImageValue或HTMLImageElement或SVGImageElement或HTMLVideoElement或HTMLCanvasElement或ImageBitmap或offscreenencanvas)”
<!DOCTYPE html>
<html>
<body>
<p>要使用的视频:</p>
<video id="video1" controls width="270" autoplay>
<source src="viedo/test.mp4" type='video/mp4'>
</video>
<canvas id="myCanvas" width="270" height="135" style="border:1px solid #d3d3d3;">
您的浏览器不支持HTML5 canvas标签。
</canvas>
<button onclick="clickfun()">截图</button>
<script>
function clickfun(){
var v=document.getElementById("video1");
var c=document.getElementById("myCanvas");
ctx=c.getContext('2d');
ctx.drawImage(v,0,0,270,135);
}
</script>
</body>
</html>
截图上传功能实现(主要使用canvas.toDataURL('image/png')这个方法)
注意:
本地测试出现Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported如何解决?
一放到服务器上面就好了,这样就不存在什么跨域问题了
原因:大概意思是canvas无法执行toDataURL方法:污染的画布无法输出。
经google 发现原来是受限于 CORS 策略,会存在跨域问题,虽然可以使用图像(比如append到页面上)但是绘制到画布上会污染画布,一旦一个画布被污染,就无法提取画布的数据,比如无法使用使用画布toBlob(),toDataURL(),或getImageData()方法;当使用这些方法的时候 会抛出一个安全错误
//将base64转换为文件
var dataURLtoBlob=function(dataurl, filename) {
var arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
}
//canvas画出该图 →调用canvas的方法生成base64编码 → 将编码转换成file对象
function printscreen(){
var video =$("#media").find("video")[0];//获取前台要截图的video对象,
var canvas = document.createElement('canvas');
var width = 400;
var height = 533;
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext('2d');//设置canvas绘制2d图,
try{
ctx.drawImage(video, 0, 0, width, height);//将video视频绘制到canvas中
}catch(err){//drawImage截取的标签有限制,请看上面,所以这里捕获一下异常,然后使用htmlToCanvas
console.error(err);
html2canvas( [ document.getElementById("media") ], {
onrendered: function(canvaS) {
canvas=canvaS;
}
});
}
var imageS = canvas.toDataURL('image/png');//canvas的api中的toDataURL()保存图像
var blob=dataURLtoBlob(imageS);
var formData = new FormData();
formData.append("file",blob);
$.ajax({
url: "...",
type: "POST",
data: formData,
contentType: false,
processData: false,
success: function (data) {
if(data.success){
}else{}
},
error: function () {}
})
}
服务器端接收
注:拼接字符串建议使用Stringbuilder
@RequestMapping(value="pImg.do",method = RequestMethod.POST)
@ResponseBody
//遇到问题:上传图片base64 SringMVC+Tomcat 报错 Request header is too large
public Object addPrintscreenImg(MultipartFile file,HttpServletRequest request){
//图片名称
String fileName=MD5.sign(UUID.randomUUID().toString().replace("-", "").toLowerCase(),"utf-8")+".png";
//保存路径upload/年/月/日
String savepdfpath="upload/"+new SimpleDateFormat("yyyy/MM/dd/").format(new Date());
//RootStatic.root_Directory为根目录 比如F:\img\
String roorSavePath=RootStatic.root_Directory+savepdfpath;
boolean b=super.uploadServer(file,roorSavePath, fileName);
log.info("截图保存->YorX:"+b+",保存路径:"+roorSavePath+",文件名:"+fileName);
if(b) {
Map map=super.AddBoToMap(request);
String dataStorePath=savepdfpath+fileName;
map.put("path", dataStorePath);
int i=yx.addVideoScreenshot(map);
if(i>0) {
log.info("截图保存成功->icbcId"+icbcId);
//RootStatic.download_prefix 为访问的url前缀
return renderSuccess(RootStatic.download_prefix+dataStorePath);//返回图片路径显示在前端
}else {
log.info("截图保存失败");
return renderError("保存失败!");
}
}else {
return renderError("上传失败!");
}
}
//文件上传
protected boolean uploadServer(MultipartFile file, String path,String fileName) {
// 判断文件是否为空
if (!file.isEmpty()) {
try {
File filepath = new File(path);
if (!filepath.exists())
filepath.mkdirs();
// 文件保存路径
String savePath = path + fileName;
log.info("图片路径->"+savePath);
File imgPath=new File(savePath);
imgPath.createNewFile();//且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件
// 转存文件
file.transferTo(imgPath);
return true;
} catch (Exception e) {
e.printStackTrace();
}
}
return false;
}
//业务对象
public Map AddBoToMap(HttpServletRequest request) {
Map map=this.updateBoToMap(request);
map.put("midAdd", this.getUserId(request));
map.put("dtAdd", creditutil.time());
return map;
}
public Map updateBoToMap(HttpServletRequest request) {
Map map=new HashMap<>();
map.put("midEdit", this.getUserId(request));
map.put("dtEdit", creditutil.time());
return map;
}
完成,亲测可用!
来源:oschina
链接:https://my.oschina.net/u/4405256/blog/4462554