利用canvas的getImageData和putImageData实现截图功能

3 篇文章 0 订阅

canvas截图

将图片用canvas绘制出来

<canvas id="myCanvas" width="400" height="400"></canvas>
let canv = document.getElementById('myCanvas');
let ctx = canv.getContext('2d');
let image = new Image();
image.onload = function() { 
	ctx.drawImage(image, 0, 0);
} 
image.src = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fup.deskcity.org%2Fpic%2F86%2Ff0%2Fe6%2F86f0e6a1c32f2c70845efba5dc4799ba.jpg&refer=http%3A%2F%2Fup.deskcity.org&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1632363064&t=64e8536db60e5a4a1f86aed977f60800";

获取截取的图片的imageData

let imageData = {};
image.onload = function() { 
	ctx.drawImage(image, 0, 0);
	/*
		使用getImageData方法获取imageData
		第一个参数是起始点X轴位置
		第二个参数是起始点Y轴位置
		第三个参数是截取的宽度
		第四个参数是截取的高度
		imageData包含四个属性
		colorSpace: "srgb"
		data: 
		Uint8ClampedArray(160000) 
		[34, 118, 180, 255, 34, 118, 180, 255, 34, 118, 180, 255, 34, 118, 180, 255, 35, 119, 181, 255, 35, 119, 181, 255, 35, 119, 181, 255, 35, 119, 181, 255, 35, 119, 181, 255, 35, 119, 181, 255, 35, 119, 181, 255, 35, 119, 181, 255, 34, 118, 182, 255, 34, 118, 182, 255, 34, 118, 182, 255, 34, 118, 182, 255, 34, 118, 182, 255, 34, 118, 182, 255, 34, 118, 182, 255, 34, 118, 182, 255, 36, 120, 184, 255, 36, 120, 184, 255, 36, 120, 184, 255, 36, 120, 184, 255, 36, 120, 184, 255, …]
		height: 200
		width: 200

		data属性它的值是一个一维数组。该数组的值,依次是每个像素的红、绿、蓝、alpha通道值,因此该数组的长度等于 图像的像素宽度 x 图像的像素高度 x 4,每个值的范围是0–255。这个数组不仅可读,而且可写,因此通过操作这个数组的值,就可以达到操作图像的目的
	*/
	imageData = ctx.getImageData(200, 150, 200, 200)
}
// 执行上面的代码会报错,原因是跨域
/*
	1. 首先没有服务器环境(如:本地的 html网页,操作本地的图片),
   就会报"Unable to get image data from canvas because the canvas has been tainted by cross-origin data"错误。
   因为本地测试用的图片是文件夹内的,js跨域限制是不能获取非同一域名下的数据的,
   而本地的位置是没有域名的,所以浏览器都认为你是跨域,导致报错。
	2. 为了阻止欺骗,浏览器会追踪 image data。
		当把一个和canvas的域不同的图片放到canvas上,这个canvas就成为 “tainted”(被污染的),浏览器就不让你操作该canvas 的任何像素。
		是为了阻止多种类型的XSS/CSRF攻击(两种典型的跨站攻击)
*/
	Uncaught DOMException: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.at Image.image.onload
// 解决方法分两步
/**
 * 第一步设置crossOrigin,设置为空字符串,相当于设置crossOrigin为anonymous
	crossOrigin有两个值
	anonymous:如果使用这个值的话就会在请求中的header中的带上Origin属性,但请求不会带上cookie和其他的一些认证信息。
	use-credentials:这个就同时会在跨域请求中带上cookie和其他的一些认证信息。
	在使用这两个值时都需要server端在response的header中带上Access-Control-Allow-Credentials属性 
**/
image.crossOrigin = '';
// 第二步需要服务端设置CORS请求跨域资源时,资源必须允许跨域,才能正常返回,最简单的方式设置响应头Access-Control-Allow-Origin: *

使用putImageData将imageData重新绘制canvas

<canvas id="canvas1" width="200" height="200"></canvas>
let cv1 = document.getElementById('canvas1').getContext('2d');
/*
	putImageData方法接收三个参数
	第一个参数imageData
	第二个参数起始点X轴位置
	第三个参数起始点y轴位置
*/
cv1.putImageData(imageData, 0, 0)
  • 效果图
    在这里插入图片描述

toDataURL获取图片的base64

document.getElementById('canvas1').toDataURL("image/png")
/*
	data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAAAXNSR0IArs4c6QAAIABJREFUeF7UvfeTJOl5JvakL9tVbWd23M7uch2wiwVAgAABEiSPZ0SeRCmkiJNCUkg/KRTSBT3v9E8pKIpHcySPIu9IHgHCWwJc7O746Z625dOn4nm//KqzsrMye2YAEuyInp7uqkrz5fu89nnfz3j53/5ehsKXYRjFXy/8P8vqXzdNs/7zFecq
*/

完整代码

// html
<div>
	<canvas id="myCanvas" width="400" height="400"></canvas>
</div>
<div>
	<canvas id="canvas1" width="200" height="200"></canvas>
</div>
// js
let canv = document.getElementById('myCanvas');
let ctx = canv.getContext('2d');
let cv1 = document.getElementById('canvas1').getContext('2d');
let image = new Image();
image.crossOrigin = '';
let imageData = {};
image.onload = function() { 
	ctx.drawImage(image, 0, 0);
	// 截图
	imageData = ctx.getImageData(100, 150, 200, 200);
	cv1.putImageData(imageData, 0, 0);
	let src1 = document.getElementById('canvas1').toDataURL("image/png");
	console.log(src1);
} 
image.src = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fup.deskcity.org%2Fpic%2F86%2Ff0%2Fe6%2F86f0e6a1c32f2c70845efba5dc4799ba.jpg&refer=http%3A%2F%2Fup.deskcity.org&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1632363064&t=64e8536db60e5a4a1f86aed977f60800";
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值