• JavaScript:canvas图像操作


    canvas是HTML5新增的元素,可以在网页上绘制图像,也可以结合其他HTML功能结合制作简单的小游戏,也是数据可视化、weGL的基础,功能非常强大。此外,还有two.js、thress.js、d3.js可视化库,这些库提供了方便的API,扩展了可视化的应用场景,丰富了可视化生态。

    本篇文章,主要介绍使用canvas对图像进行简单处理,以及canvas对图像数据转换的一些基本应用。

    在前端开发的业务中,有时候需要在网页中动态绘制比较复杂的图像,图像中存在图片,因此就使用canvas进行绘制。

    ctx.drawImage():

    参数:

    • image:绘制的image对象,除了img元素外还可以是canvas元素,svg元素、video元素、imageBitmap数据
    • x:起点的横坐标
    • y:起点的纵坐标
    • width:绘制区域的宽度
    • height:绘制区域的高度
    let ctx = canvas.getContext('2d');
    let img = document.getElementById('img');
    img.onload = function (){
    ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    有时候我们需要把绘制好的图片传给服务器端或者做其他的操作,因此就需要获取文件内容

    canvas.toDataURL()可以把绘制的图片读取为base64格式的数据

    canvas.toDataURL():

    let url = canvsa.toDataURL();
    console.log(res);
    
    • 1
    • 2

    效果如下:
    在这里插入图片描述
    这样可以通过img进行展示和下载
    如果不想用base64格式保存或者传输,还可以使用toBlob()方法读取为blob类型的数据

    canvas.toBlob():
    参数:

    • calback:回调函数,用于获取返回的数据
    • type:图片的类型
    • quality:图片的质量,取值为0-1之间

    方法返回一个blob对象

    canvas.toBlob((res) => {
    	console.log(res)
    });
    
    • 1
    • 2
    • 3

    效果如下:
    在这里插入图片描述
    可以通过blob对象的一些方法和File构造器结合使用生成一个文件

    canvas.toBlob((res) => {
    	res.arrayBuffer().then(buffer => {
          let file = new File(Array.prototype.slice.call(buffer,0, buffer.byteLength), 'qrcode.png');
        });
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    blob数据 也可以通过URL.createOjectDataURL()转换成一个地址

    canvas.toBlob((res) => {
    	 let blobUrl = URL.createObjectURL(res);
        console.log(blobUrl)
    });
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述
    canvas除了可以绘制元素之外,还可以对图像数据进行绘制,这些数据通常是用一维数组存储的记录rgb数值的数据
    canvas可以通过getImageData()方法获得图像数据

    let ctx = canvas.getContext('2d);
    let img = document.getElementById('img');
    img.onload = function (){
    ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
    let imgData = ctx.getIamgeData(img);
    console.log(imageData);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述
    可以看到imageData对象中有一个data属性,就是一个一维数组,然后可以把它重新绘制

    ctx.putImageData(imageData, 0, 0, 0, 0 , canvas.width, canvas.height);
    
    • 1

    在这里插入图片描述
    这样就又重新绘制上去了,我们也可以对数据进行操作后再绘制

    let ctx = canvas.getContext('2d);
    let img = document.getElementById('img');
    img.onload = function (){
    	ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
    	let imgData = ctx.getImageData(img);
    	for(let i = 0, len = imageData.data.length; i < len; i++){
       		imageData.data[i] = imageData.data[i] *2;
    	}
       	ctx.putImageData(imageData, 0, 0);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    效果如下:
    在这里插入图片描述
    我们也可以自己生成类似的数据进行绘制

    使用 ImageData构造函数创建一个ImageData对象,然后创建一个Unit8ClampedArray数据用于存储rgb数值,赋值给ImageData对象,然后通过putIamgeData绘制
    ImageData()构造函数接收三个参数
    参数:

    • data:Unit8ClampedArray,Unit8ClampedArray的长度应当是4 * width * height,之所以乘以4是因为一个像素点需要使用四个数值分别表示它的rgba值
    • width:图像的宽度
    • height:图像的高度
    let ctx = canvas.getContext('2d);
    let width = 300
    let height = 300
    let data = new Uint8ClampedArray(width * height * 4);
    for(let i = 0; i < data.length; i++){
    	data[i] = Math.floor(Math.random() * 256) * 2;
    }
    let imageData = new ImageData(data, width, height);
    ctx.putImageData(imageData, 0, 0);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    效果如下
    在这里插入图片描述

  • 相关阅读:
    OpenNebula的配置与应用(二)
    深度强化学习第 1 章 机器学习基础
    Java回顾-反射
    区间贪心问题合集
    计组实践实验9——使用CMStudio设计基于分段模型机微程序指令(2)
    Network Shell (Netsh)
    C++报错illegal instruction
    15:00面试,15:06就出来了,问的问题有点变态。。。
    Educational Codeforces Round 134 (Rated for Div. 2) A~D
    Python实践提!
  • 原文地址:https://blog.csdn.net/qq_40850839/article/details/127413470