2014-04-16 23 views
40

Tôi có một biểu mẫu cho phép người dùng tải lên hình ảnh.Chia tỷ lệ hình ảnh để vừa với canvas

Sau khi hình ảnh được tải, chúng tôi thực hiện một số mở rộng trên nó để giảm kích thước của nó trước khi chúng tôi chuyển nó trở lại máy chủ.

Để làm điều này, chúng tôi đặt nó trên vải và thao tác ở đó.

Mã này sẽ làm cho hình ảnh thu nhỏ trên vải, với bạt kích thước 320 x 240px:

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

... nơi canvas.width và canvas.height là chiều cao và chiều rộng xa rộng yếu tố dựa trên kích thước của hình ảnh gốc.

Nhưng khi tôi đi đến sử dụng mã:

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

... Tôi chỉ nhận được một phần của hình ảnh trên vải, trong trường hợp này góc trên bên trái. Tôi cần toàn bộ hình ảnh được thu nhỏ để vừa với canvas, mặc dù kích thước hình ảnh thực tế lớn hơn kích thước canvas 320x240.

Vì vậy, đối với mã ở trên, chiều rộng và chiều cao là 1142x856, vì đó là kích thước hình ảnh cuối cùng. Tôi cần phải duy trì kích thước đó để chuyển thông tin về máy chủ khi biểu mẫu được gửi, nhưng chỉ muốn một chế độ xem nhỏ hơn xuất hiện trong canvas cho người dùng.

Tôi thiếu gì ở đây? Mọi người có thể chỉ tôi một cách đàng hoàng được không nào?

Rất cám ơn trước.

Trả lời

64

Cung cấp hình ảnh nguồn (img) kích thước như hình chữ nhật đầu tiên:

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

Hình chữ nhật thứ hai sẽ được kích thước đích (những gì hình chữ nhật nguồn sẽ được thu nhỏ để).

Cập nhật 2016/6: Đối với tỉ lệ và định vị (ala CSS' cover "phương pháp), hãy kiểm tra:
Simulation background-size: cover in canvas

+2

Perfect. Rất rất cảm ơn. :) – dradd

+0

Điều này hoàn hảo, +1. Điểm nhanh - bạn đang thiếu dấu ngoặc đóng trên hàm 'drawImage()'. Lộn xộn với OCD của tôi một chút;) – Frits

+1

@Frits lol, tôi biết ý bạn là gì. Đã thêm :) – K3N

87

bạn đã thực hiện các lỗi, cho cuộc gọi thứ hai, để thiết lập kích thước của nguồn đến kích thước của mục tiêu.
Dù sao tôi đặt cược mà bạn muốn tỉ lệ tương tự cho các hình ảnh thu nhỏ lại, vì vậy bạn cần phải tính toán nó:

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); 

tôi cũng giả sử bạn muốn tập trung hình ảnh, vì vậy mã sẽ là:

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); 
} 

bạn có thể nhìn thấy nó trong một jsbin đây: http://jsbin.com/funewofu/1/edit?js,output

+0

cảm ơn bạn, đoạn mã này đã giúp tôi tiết kiệm thời gian :) –

+4

Cảm ơn bạn! Tôi đã thay đổi Math.min() thành Math.max() để chia tỷ lệ và cắt hình ảnh cho vừa với canvas. Điều này rất hữu ích! – Daantje

+1

nhưng điều này tạo ra hình ảnh mờ khi tôi tạo ra hình ảnh lớn từ kích thước nhỏ. nó bị mờ .. bất kỳ giải pháp nào? xin vui lòng – saadk

Các vấn đề liên quan