Обрезать точный центр источника изображения холста

#javascript #css #html #canvas

#javascript #css #HTML #холст

Вопрос:

Я создал форму ввода, которая принимает загруженные файлы в элемент canvas. Поскольку разные изображения имеют разные размеры, загруженное изображение всегда растягивается, чтобы соответствовать моему размеру холста, который равен 400 * 350 .

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

 <input type='file' id="fileUpload" />
<canvas id="up_canvas" width="400" height="350" style="border: 1px solid red;"></canvas>

<script>
//get input as canvas
function el(id){return document.getElementById(id);}

var canvas_one  = el("up_canvas");
var context_one = canvas_one.getContext("2d");

function readImage() {
if ( this.files amp;amp; this.files[0] ) {
    var FR= new FileReader();
    FR.onload = function(e) {
       var img = new Image();
       img.onload = function() {
         context_one.drawImage(img, 0, 0, 400, 350);
       };
       img.src = e.target.result;
    };       
    FR.readAsDataURL( this.files[0] );
}
}

el("fileUpload").addEventListener("change", readImage, false);
</script>
  

Ответ №1:

Чтобы нарисовать определенную часть изображения, вы должны указать дополнительные параметры в drawImage() функции. Если вы вызываете его с 9 аргументами, это void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight); , где s означает источник, и вы указываете, какую часть предоставленного изображения вы хотите нарисовать.

Мы всегда обрезаем прямоугольник размером 400×350, но нам нужно вычислить атрибуты sx и sy . В вашем случае вы хотите нарисовать изображение следующим образом:

 context_one.drawImage(img, 
                      (img.width - 400) / 2,   // sx, 200 pixels to the left from center
                      (img.height - 350) / 2,  // sy, 175 pixels above center
                      400, 350, 0, 0, 400, 350);  // sw, sh, dx, dy, dw, dh
  

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

 context_one.drawImage(img, 
                      Math.max(0, (img.width - 400) / 2),
                      Math.max(0, (img.height - 350) / 2), 
                      400, 350, 0, 0, 400, 350);  // sw, sh, dx, dy, dw, dh