2014-04-16 116 views
40

我有一个表单,允许用户上传图像。缩放图像以适应画布

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

要做到这一点,我们把它放在画布上并在那里操作。

此代码将呈现缩放图像在画布上,随着尺寸的画布320×240像素:

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

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

但是当我去使用的代码:

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

......我只在画布上获得图像的一部分,在这种情况下,左上角。尽管实际图像尺寸大于320x240的画布大小,我仍然需要“缩放”整个图像以适应画布。

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

我在这里错过了什么?任何人都可以指出我正确的方向吗?

非常感谢提前。

回答

64

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

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

第二矩形将目标大小(什么源矩形将被调整来)。

更新六分之二千〇一十六:对于纵横比和定位(ALA CSS” “盖” 的方法),检查出:
Simulation background-size: cover in canvas

+2

完美。非常感谢。 :) – dradd

+0

这是完美的+1。快速点 - 你在'drawImage()'函数中缺少右括号。用我的强迫症一点点;) – Frits

+1

@Frits大声笑,我知道你的意思。增加:) – K3N

87

所做的错误,对于第二呼叫,以设置源的大小为目标的大小。
无论如何,我敢打赌,你想对缩放后的图像相同的纵横比,所以你需要计算它:

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

+0

谢谢,这段代码节省了我一些时间:) –

+4

谢谢!我将Math.min()更改为Math.max()以缩放和裁剪图像以适应画布。这非常有帮助! – Daantje

+1

但是,当我从小尺寸生成大图像时,会生成模糊图像。它变得模糊..任何解决方案?请 – saadk