html截图 viedo标签截图 上传图片到服务器 java代码保存图片(完整)

对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”:提供的值不是类型“(CSSImageValueHTMLImageElementSVGImageElementHTMLVideoElementHTMLCanvasElementImageBitmapoffscreenencanvas)”

<!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;
    }

完成,亲测可用! 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值