Масштабирование изображения для размещения на холсте

У меня есть форма, которая позволяет пользователю загружать изображение.

Как только изображение загружено, мы выполняем некоторое масштабирование на нем, чтобы уменьшить его размер, прежде чем передавать его обратно на сервер.

Для этого мы помещаем его на холст и манипулируем им там.

Этот код отобразит масштабированное изображение на холсте с холстом размером 320 x 240 пикселей:

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, так как это конечный размер изображения. Мне нужно поддерживать этот размер, чтобы передать beck серверу, когда форма отправлена, но только хочет, чтобы меньший вид его отображался в холсте для пользователя.

Что мне здесь не хватает? Может ли кто-нибудь указать мне в правильном направлении?

Большое спасибо заранее.

Ответ 1

Укажите исходный образ (img) в качестве первого прямоугольника:

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

Второй прямоугольник будет размером назначения (какой прямоугольник источника будет масштабироваться).

Обновление 2016/6. Для формата и позиционирования (метод обложки "ala CSS" ): Симуляция фона: обложка в холсте

Ответ 2

Вы сделали ошибку для второго вызова, чтобы установить размер источника в размере цели.
В любом случае, я уверен, что вы хотите иметь одинаковое соотношение сторон для масштабированного изображения, поэтому вам нужно вычислить его:

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