使用JavaScript Canvas(平滑地)调整图像大小
使用JavaScript Canvas(平滑地)调整图像大小
我正在尝试使用canvas调整一些图像的大小,但我不知道如何使它们更加平滑。
在Photoshop、浏览器等软件中,它们使用一些算法,例如双三次插值算法、双线性插值算法等,但我不知道它们是否内置到canvas中。
这是我的jsfiddle链接:http://jsfiddle.net/EWupT/
var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); canvas.width=300 canvas.height=234 ctx.drawImage(img, 0, 0, 300, 234); document.body.appendChild(canvas);
第一个是普通的大小调整图像标签,第二个是canvas。请注意,canvas的图像不是那么平滑。我该如何实现\"平滑度\"呢?
admin 更改状态以发布 2023年5月23日
自从Trung Le Nguyen Nhat的fiddle根本是错误的(它仅在最后一步使用原始图像)
我写了自己的通用fiddle并进行了性能比较:
基本上就是:
img.onload = function() { var canvas = document.createElement('canvas'), ctx = canvas.getContext("2d"), oc = document.createElement('canvas'), octx = oc.getContext('2d'); canvas.width = width; // destination canvas size canvas.height = canvas.width * img.height / img.width; var cur = { width: Math.floor(img.width * 0.5), height: Math.floor(img.height * 0.5) } oc.width = cur.width; oc.height = cur.height; octx.drawImage(img, 0, 0, cur.width, cur.height); while (cur.width * 0.5 > width) { cur = { width: Math.floor(cur.width * 0.5), height: Math.floor(cur.height * 0.5) }; octx.drawImage(oc, 0, 0, cur.width * 2, cur.height * 2, 0, 0, cur.width, cur.height); } ctx.drawImage(oc, 0, 0, cur.width, cur.height, 0, 0, canvas.width, canvas.height); }
您可以使用下采样来获得更好的结果。大多数浏览器在调整图像大小时似乎使用线性插值而不是双三次插值。
(更新 规格中已添加质量属性 imageSmoothingQuality
,目前仅在Chrome中可用。)
除非选择不平滑或最近邻,否则浏览器将始终在缩小图像后对其进行插值处理,因为这个函数是一个低通滤波器,以避免混叠现象。
双线性插值使用2x2像素进行插值,而双三次插值使用4x4像素,因此通过分步进行插值,你可以使用双线性插值获得接近双三次插值的结果,如所生成的图像所示。
var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var img = new Image(); img.onload = function () { // set size proportional to image canvas.height = canvas.width * (img.height / img.width); // step 1 - resize to 50% var oc = document.createElement('canvas'), octx = oc.getContext('2d'); oc.width = img.width * 0.5; oc.height = img.height * 0.5; octx.drawImage(img, 0, 0, oc.width, oc.height); // step 2 octx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5); // step 3, resize to final size ctx.drawImage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5, 0, 0, canvas.width, canvas.height); } img.src = "//i.imgur.com/SHo6Fub.jpg";
根据您的缩放程度,如果差异不大,可以跳过步骤2。
在演示中,您可以看到新的结果现在与图像元素更加相似。