缩放图像以适合画布

Posted

技术标签:

【中文标题】缩放图像以适合画布【英文标题】:Scaling an image to fit on canvas 【发布时间】:2014-05-31 00:56:16 【问题描述】:

我有一个允许用户上传图片的表单。

加载图像后,我们会对其进行一些缩放,以便在将其传回服务器之前减小其文件大小。

为此,我们将其放置在画布上并在那里进行操作。

此代码将在画布上渲染缩放后的图像,画布大小为 320 x 240px:

ctx.drawImage(img, 0, 0, canvas.width, canvas.height)

... 其中 canvas.width 和 canvas.height 是图像高度和宽度 x 基于原始图像大小的缩放因子。

但是当我去使用代码时:

ctx.drawImage(img, 0, 0, canvas.width, canvas.height, 0, 0, canvas.width, canvas.height

...我只得到画布上的部分图像,在这种情况下是左上角。尽管实际图像尺寸大于 320x240 画布尺寸,但我需要将整个图像“缩放”以适合画布。

所以对于上面的代码,宽度和高度都是 1142x856,因为这是最终的图像尺寸。在提交表单时,我需要保持该大小以传递给服务器,但只希望在用户的画布中显示一个较小的视图。

我在这里缺少什么?谁能指出我正确的方向吗?

非常感谢。

【问题讨论】:

【参考方案1】:

我猜您希望将图像缩放到更小的尺寸,而不会丢失尺寸的比例。我有一个解决方案。

var ratio = image.naturalWidth / image.naturalHeight;
var width = canvas.width;
var height = width / ratio;
ctx.drawImage(image, 0, 0, width, height);

该比例将保持不变。在画布上绘制的图像将具有相同的比例。如果图像的高度很长,您可以使用 if 循环,您可以将 canvas.width 替换为其他宽度

【讨论】:

【参考方案2】:

提供源图像(img)大小作为第一个矩形:

ctx.drawImage(img, 0, 0, img.width,    img.height,     // source rectangle
                   0, 0, canvas.width, canvas.height); // destination rectangle

第二个矩形将是目标大小(源矩形将被缩放到什么位置)。

2016/6 更新:对于纵横比和定位(ala CSS 的“覆盖”方法),请查看:Simulation background-size: cover in canvas

【讨论】:

这是完美的,+1。快速点 - 您缺少 drawImage() 函数上的右括号。有点搞砸我的强迫症;) 非常适合我的需求。当表单边距发生变化时,它使我不必摆弄我的图像文件的大小/比例。谢谢;)【参考方案3】:

您在第二次调用时出错,将源的大小设置为目标的大小。 无论如何,我打赌你想要缩放图像的相同纵横比,所以你需要计算它:

var hRatio = canvas.width / img.width    ;
var vRatio = canvas.height / img.height  ;
var ratio  = Math.min ( hRatio, vRatio );
ctx.drawImage(img, 0,0, img.width, img.height, 0,0,img.width*ratio, img.height*ratio);

我还假设您想将图像居中,所以代码是:

function drawImageScaled(img, ctx) 
   var canvas = ctx.canvas ;
   var hRatio = canvas.width  / img.width    ;
   var vRatio =  canvas.height / img.height  ;
   var ratio  = Math.min ( hRatio, vRatio );
   var centerShift_x = ( canvas.width - img.width*ratio ) / 2;
   var centerShift_y = ( canvas.height - img.height*ratio ) / 2;  
   ctx.clearRect(0,0,canvas.width, canvas.height);
   ctx.drawImage(img, 0,0, img.width, img.height,
                      centerShift_x,centerShift_y,img.width*ratio, img.height*ratio);  

您可以在此处的 jsbin 中看到它: http://jsbin.com/funewofu/1/edit?js,output

【讨论】:

谢谢!我将 Math.min() 更改为 Math.max() 以缩放和裁剪图像以适合画布。这很有帮助! 但是当我从小尺寸生成大图像时,这会生成模糊图像。它变得模糊..任何解决方案?请 非常感谢@gamealchemist。通读这本书帮助我了解了如何获得按比例缩小的图像,而我自己永远才能解决这个问题。谢谢! @saadk knowyourmeme.com/photos/996305-zoom-and-enhance ;)

以上是关于缩放图像以适合画布的主要内容,如果未能解决你的问题,请参考以下文章

html5图像旋转缩放并上传

按比例调整图像大小以适合 HTML5 画布

如何在不损失图像质量的情况下调整图像大小以适合小型 HTML5 画布? [复制]

缩放图像以适合边界框

AS3 图像在内部旋转/缩放以适合精灵

如何以 100% 的页面宽度打印画布图像?