HTML画布:如何缩放图像以适应大小而不拉伸?

10

我正在使用下面的代码在画布中绘制和缩放图像。问题是渲染在内部的图像被拉伸以适应。

如果可能,我希望它基于宽度进行比例缩放但保持其长宽比。

有任何想法吗?

//IMAGE LOADER
var canvas = document.getElementById('image-canvas');
var canvas2 = document.getElementById('image-canvas2');
ctx = canvas.getContext('2d');
ctx2 = canvas2.getContext('2d');

// Trigger the imageLoader function when a file has been selected
var fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', imageLoader, false);

function imageLoader() {
    var reader = new FileReader();
    reader.onload = function(event) {
        img = new Image();
        img.onload = function(){
            ctx.drawImage(img,0,0,canvas.width, canvas.height);
            ctx2.drawImage(img,0,0,canvas.width, canvas.height);
        }
        img.src = reader.result;
    }
    reader.readAsDataURL(fileInput.files[0]);
}

1
你知道正确的比例是多少吗?在绘制时,你可以直接应用正确的比例。如果你不知道它,你可以在DOM上渲染并查询图像的宽度/高度。 - Ruan Mendes
1个回答

29

您可以将图片添加到DOM中来确定其尺寸。一旦您知道比例,就可以将图像缩放以适应画布。

ratio = width / height;
width = height * ratio;
height = width / ratio;

以下内容适用于横向或纵向图片。

var canvas = document.getElementById('image-canvas');
var canvas2 = document.getElementById('image-canvas2');
var ctx = canvas.getContext('2d');
document.getElementById('fileInput').addEventListener('change', imageLoader, false);

function imageLoader() {
    var reader = new FileReader();
    reader.onload = function(event) {
        var img = new Image();
        img.onload = function(){
            var ct = document.getElementById('measure'); 
            ct.appendChild(img);
            var wrh = img.width / img.height;
            var newWidth = canvas.width;
            var newHeight = newWidth / wrh;
            if (newHeight > canvas.height) {
                newHeight = canvas.height;
                newWidth = newHeight * wrh;
            }
            ct.removeChild(img);
            ctx.drawImage(img,0,0, newWidth , newHeight);
        }
        img.src = reader.result;
    }
    reader.readAsDataURL(fileInput.files[0]);
}
/* Add image to the DOM here so user can't see it */
#measure { position: absolute; left: -10000px; top: -100000px;}
canvas { border: 1px solid red; }
<canvas id="image-canvas" width="300" height="300"></canvas>
<input type="file" id="fileInput" />
<div id="measure"></div>

你可以在这里玩耍

非常棒的回复。非常感谢! - Alejandro Gorgal
太棒了!节省了我很多工作,谢谢伙计! - Jürgen 'Kashban' Wahlmann
当我在Fireworks的响应式视图中尝试时,一切正常,但当我从我的手机上尝试时,它就不行了。有什么想法吗? - myhappycoding
@galeonweb 你应该提出一个新问题并将其链接到此问题,发布你使用的代码、尝试过程中遇到的错误以及你的期望结果。请不要在现有问题下提出新问题,这会增加太多噪音。 - Ruan Mendes
好的,对不起。我不确定是否可以重复提问,以及如何操作。 - myhappycoding
如果您展示了代码的具体用法,那么它就不是重复的问题。您的问题很可能是其他方面引起的,因此提出一个单独的问题可能有助于其他可能遇到相同问题的人。 - Ruan Mendes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接