Open Toninie opened 6 years ago
这个是去年使用canvas对图片尺寸进行压缩、裁剪时总结的一些经验,重新整理了内容搬来这里。
本文提及的现象可以通过此demo感受一下,另外安利一下后续整理集成的海报编辑插件
使用canvas来显示图片时,一般用到drawImage这个方法,调用方式有3种。
canvas
drawImage
context.drawImage(img,x,y);
context.drawImage(img,x,y,width,height);
context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
其中参数的含义:
img
sx
sy
swidth
sheight
x
y
width
height
width或height与图片实际尺寸不同时,即会自动被压缩或拉伸。
使用canvas显示图片时,常见的情况是图片实际宽度与canvas不匹配,需要对图片尺寸进行压缩,如果直接用canvas的方法去强制压缩以适应尺寸,例如:
var c = $("#myCanvas")[0], ctx = c.getContext("2d"), img = new Image(), maxWidth = $(window).width(); img.src = ".../image/xxx.jpg"; img.onload = function () { c.width = maxWidth; c.height = maxWidth * this.height / this.width; ctx.drawImage(img,0,0,c.width,c.height); }
显示出来的图片很容易出现模糊或者锯齿,如果原图尺寸与canvas尺寸差距较大时,这种现象会更明显。
可以将图片按原尺寸呈现,再通过css去调整canvas的尺寸,这种方法是不会对加载到canvas的图片数据产生影响。
css
img.onload = function () { c.width = this.width;// 将canvas宽度设置为原图宽度 c.height = this.height;// 将canvas高度设置为原图高度 ctx.drawImage(img,0,0,c.width,c.height); c.style.width = "100%";// 修改canvas的样式,适应页面 }
之前已经提到,原图尺寸与canvas尺寸差距较大时,直接通过canvas压缩图片会出现锯齿、模糊等现象,质量很难得到保证,但是要在前端对图片数据进行修改,还是离不开canvas。 要实现高质量的图片压缩,首先还是按原尺寸将图片加载到canvas上,然后获取数据
context.getImageData(int x,int y,int width,int height)
在canvas上从(x,y)开始,获取宽为width、高为height的图片数据。该方法返回的是一个CanvasPixelArray对象。 该对象具有width、height、data等属性,其中data属性可以看作一个数组来操作。该数组每4个元素对应一个像素点,依次记录像素点的rgba数值,像素点的顺序是从左到右,从上至下。 可以通过算法将图片的像素点从原尺寸压缩成目标尺寸,再重新加载到canvas上
(x,y)
CanvasPixelArray
data
rgba
context.putImageData(CanvasPixelArray data,int x,int y)
能够自定义算法去操作图片每个像素点的rgba数据,这里的自由度就非常高了。这里安利一个现成的js插件scale.js,能够比较高质量地压缩图片,当然使用的算法也比较简直接,就是通过面积加权的算法,来得出压缩后每个像素点的颜色值。
本文提及的现象可以通过此demo感受一下,另外安利一下后续整理集成的海报编辑插件
canvas显示图片
使用
canvas
来显示图片时,一般用到drawImage
这个方法,调用方式有3种。其中参数的含义:
img
规定要使用的图像、画布或视频。sx
可选,开始剪切的 x 坐标位置。sy
可选,开始剪切的 y 坐标位置。swidth
可选,被剪切图像的宽度。sheight
可选,被剪切图像的高度。x
在画布上放置图像的 x 坐标位置。y
在画布上放置图像的 y 坐标位置。width
可选,要使用的图像的宽度。height
可选。要使用的图像的高度。width
或height
与图片实际尺寸不同时,即会自动被压缩或拉伸。现象和问题
使用
canvas
显示图片时,常见的情况是图片实际宽度与canvas
不匹配,需要对图片尺寸进行压缩,如果直接用canvas
的方法去强制压缩以适应尺寸,例如:显示出来的图片很容易出现模糊或者锯齿,如果原图尺寸与
canvas
尺寸差距较大时,这种现象会更明显。解决方法
显示优化
可以将图片按原尺寸呈现,再通过
css
去调整canvas
的尺寸,这种方法是不会对加载到canvas的图片数据产生影响。压缩优化
之前已经提到,原图尺寸与
canvas
尺寸差距较大时,直接通过canvas
压缩图片会出现锯齿、模糊等现象,质量很难得到保证,但是要在前端对图片数据进行修改,还是离不开canvas
。 要实现高质量的图片压缩,首先还是按原尺寸将图片加载到canvas上,然后获取数据在
canvas
上从(x,y)
开始,获取宽为width
、高为height
的图片数据。该方法返回的是一个CanvasPixelArray
对象。 该对象具有width
、height
、data
等属性,其中data
属性可以看作一个数组来操作。该数组每4个元素对应一个像素点,依次记录像素点的rgba
数值,像素点的顺序是从左到右,从上至下。 可以通过算法将图片的像素点从原尺寸压缩成目标尺寸,再重新加载到canvas
上能够自定义算法去操作图片每个像素点的rgba数据,这里的自由度就非常高了。这里安利一个现成的js插件scale.js,能够比较高质量地压缩图片,当然使用的算法也比较简直接,就是通过面积加权的算法,来得出压缩后每个像素点的颜色值。