2014-04-16 117 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