canvas像素操作 取色器 写入像素数据 缩放和反锯齿 保存图片

博客简介

HTML5中的canvas允许我们直接对像素进行操作,我们可以通过ImageData对象操纵像素数据,读取或将数据数组写入该对象中。这里还会介绍如何控制图像使其平滑(反锯齿)以及如何从Canvas画布中保存图像。

  • imageData对象
  • 读取或写入imageDate对象
  • 缩放和反锯齿
  • 保存图片

ImageData对象

ImageData对象中存储着canvas对象真实的像素数据,包含以下只读属性

  • iwidth:图片的宽度,单位px
  • height:图片的高度,单位px
  • data:Uint8ClampedArray类型的一维数组,包含着RGBA格式的整型数据,范围在0至255之间(包括255)。
  • data属性返回一个像素数组 Uint8ClampedArray,它可以被使用作为查看初始像素数据。每个像素用4个1bytes值(按照红,绿,蓝和透明值的顺序; 这就是"RGBA"格式) 来代表。每个颜色值部份用0至255来代表。每个部份被分配到一个在数组内连续的索引,左上角像素的红色部份在数组的索引0位置。像素从左到右被处理,然后往下,遍历整个数组。
  • 获取i行j列的R/G/B/A值:
imageData.data[((行数-1)*imageData.width + (列数-1))*4 - 1 + 1/2/3/4];
  • 获取像素数组Uint8ClampedArray的大小:
var numBytes = imageData.data.length;

创建一个ImageData对象

一般的,创建一个ImageData对象,我们可以使用createImageData方法:

  • var myImageData = ctx.createImageData(width, height):创建一个新的尺寸为width,height的ImageData对象,所有的像素被预设为黑色透明。
  • var myImageData = ctx.createImageData(anotherImageData):创建一个被anotherImageData对象指定的相同像素的ImageData对象。这个新的对象像素全部被预设为透明黑。这个并非复制了图片数据。
var myImageData = ctx.createImageData(width, height);
var myImageData = ctx.createImageData(anotherImageData);

获取场景canvas区域的ImageData对象

我们可以通过getImageData方法获取canvas指定区域的像素数据:

  • getImageData(x,y,width,height):返回一个ImageData对象,该对象描述了(x,y,x+width,y+height)区域的像素

举例:取色器

这个例子中,我们将返回鼠标位置的像素:

  • 获取鼠标的位置x,y
  • 获取该位置的ImageData对象
  • 获取对象的数据
  • 将数据返回,并且用该RGBA值绘制颜色
var img=new Image();
window.onload=function()
{
    img.src="spiderMan.jpg";//获取图片
    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext('2d');
    img.onload=function()
    {
        ctx.drawImage(img,0,0,400,300);//画出图片
        //获取ImageData对象
        canvas.addEventListener("mousemove",function(e)
        {
            var x=e.layerX;
            var y=e.layerY;//获取坐标
            var imageData=ctx.getImageData(x,y,1,1);//获取x,y处像素1*1的图片
            var data=imageData.data;//获取像素数据
            var r=data[0];
            var g=data[1];
            var b=data[2];
            var a=data[3];
            var color="rgba("+r+","+g+","+b+","+a+")";
            ctx.clearRect(0,305,400,400)
            ctx.save();
            ctx.fillStyle=color;
            ctx.fillRect(0,305,100,40);//绘制矩形
            ctx.font="15px 幼圆";
            ctx.save();
            ctx.fillStyle=" #7B68EE";
            ctx.fillRect(0,375,250,40);
            ctx.restore();
            ctx.fillText("光标处像素="+color,0,400);
            ctx.restore();
        })
    }
}

在这里插入图片描述

在场景canvas中写入像素数据

我们通过getImageData方法获取canvas指定区域的像素数据,同时也可以用putImageData()方法将像素写入写入canvas中

  • putImageData(imageData,x,y):将ImageData对象代表的图片绘制在x,y位置
  • 直接修改ImageData.data就能够改变ImageData对象

putImageData举例

以下我们将会操纵一张图片像素,取出像素值后,对它进行灰度反相操作,我们设置两个函数grayscale 和invert 来实现:

  • grayscale 灰度处理 :x = 0.299r + 0.587g + 0.114b
function grayscale()//灰度
{
    for(var i=0;i<data.length;i+=4)
    {
        avg=0.299*data[i] + 0.587*data[i+1] + 0.114*data[i+2];
        data[i]=data[i+1]=data[i+2]=avg;
    }
    ctx.clearRect(0,0,canvas.width,canvas.height);
    ctx.putImageData(imageData,0,0);
}
  • invert 反相处理 :x=255-i
function intervar()//反相
{
    for(var i=0;i<data.length;i+=4)
    {
        data[i]=255-data[i];//r
        data[i+1]=255-data[i+1];//g
        data[i+2]=255-data[i+2];//b
    }
    ctx.clearRect(0,0,canvas.width,canvas.height);
    ctx.putImageData(imageData,0,0);
}

最后添加监听

  var invertbtn = document.getElementById('invertbtn');
  invertbtn.addEventListener('click', intervar);

  var grayscalebtn = document.getElementById('grayscalebtn');
  grayscalebtn.addEventListener('click', grayscale);

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

扫描二维码关注公众号,回复: 8941029 查看本文章

缩放和反锯齿

关于canvas操作图像的放缩,我们在前面已经介绍过了,通过drawImage(x,y,w,h)来实现,放缩过程中默认是反锯齿的,如果我们想要去掉反锯齿,看到具体的像素,可以使用imageSmoothingEnabled属性:

  • imageSmoothingEnabled锯齿:如果为true,则展示反锯齿,为false展示锯齿

缩放和反锯齿举例

var img=new Image();
img.src="../纸飞机.jpg";
var canvas;
var able=1;
img.onload=function()
{
    draw(this);
}
function toggleSmoothing()
{
    able=able?false:true;
    ctx.imageSmoothingEnabled=able;
}
function show(e)
{
    var x=e.layerX;
    var y=e.layerY;//获取坐标
    ctx.clearRect(500,0,200,200);
    ctx.drawImage(canvas,Math.abs(x-5),Math.abs(y-5),10,10,500,0,200,200);
}
function draw(img) {
  canvas = document.getElementById('canvas');
  ctx = canvas.getContext('2d');
  ctx.drawImage(img, 0, 0,480,300);
  img.style.display = 'none';

  var smoothbtn = document.getElementById('smoothbtn');//获取区域
  smoothbtn.addEventListener('click',toggleSmoothing);
  canvas.addEventListener('mousemove',show);
}

在这里插入图片描述
在这里插入图片描述

保存图片

HTMLCanvasElement 提供一个toDataURL()方法,此方法在保存图片的时候非常有用。它返回一个包含被类型参数规定的图像表现格式的数据链接。返回的图片分辨率是96dpi。

  • canvas.toDataURL(‘image/png’) :默认设定。创建一个PNG图片。
  • canvas.toDataURL(‘image/jpeg’, quality):创建一个JPG图片。你可以有选择地提供从0到1的品质量,1表示最好品质,0基本不被辨析但有比较小的文件大小。
    当你从画布中生成了一个数据链接,例如,你可以将它用于任何< image >元素,或者将它放在一个有download属性的超链接里用于保存到本地
  • canvas.toBlob(callback, type, encoderOptions):这个创建了一个在画布中的代表图片的Blob对像。

用超链接保存图片:

我们对以上的图片稍加修改,并且插入超链接

var img=new Image();
img.src="../纸飞机.jpg";
var canvas;
var able=1;
img.onload=function()
{
    draw(this);
}
function toggleSmoothing()
{
    able=able?false:true;
    ctx.imageSmoothingEnabled=able;
}
function show(e)
{
    var x=e.layerX;
    var y=e.layerY;//获取坐标
    ctx.clearRect(500,0,200,200);
    ctx.drawImage(canvas,Math.abs(x-5),Math.abs(y-5),10,10,500,0,200,200);
}
function draw(img) {
  canvas = document.getElementById('canvas');
  ctx = canvas.getContext('2d');
  ctx.drawImage(img, 0, 0,480,300);
  img.style.display = 'none';

  var smoothbtn = document.getElementById('smoothbtn');//获取区域
  smoothbtn.addEventListener('click',toggleSmoothing);
  canvas.addEventListener('mousemove',show);
  canvas.addEventListener("click",function(){
    var area=document.getElementsByTagName("a")[0];
    area.setAttribute("href",canvas.toDataURL("纸飞机",1));
  })
}

当图片被点击时,就会生成一个toDataURL对象,点击超链接则会下载图片:
在这里插入图片描述
在这里插入图片描述
图片下载完成

发布了123 篇原创文章 · 获赞 136 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_44307065/article/details/104110109