Javascript 在iOS Safari中缩放图像并将其绘制到画布时,宽度是正确的,但高度是压缩的

Javascript 在iOS Safari中缩放图像并将其绘制到画布时,宽度是正确的,但高度是压缩的,javascript,ios,ipad,canvas,mobile-safari,Javascript,Ios,Ipad,Canvas,Mobile Safari,我正在加载一个图像,然后将该图像绘制到画布上。我也在缩小图像以适应画布。当我这样做时,图像以适当的宽度绘制到画布上,但高度约为画布实际高度的1/4 //Calculate height from canvas-to-image width ratio var width = canvas.width; var height = ( width / img.width ) * img.height; //Draw scale image (This results in a squished h

我正在加载一个图像,然后将该图像绘制到画布上。我也在缩小图像以适应画布。当我这样做时,图像以适当的宽度绘制到画布上,但高度约为画布实际高度的1/4

//Calculate height from canvas-to-image width ratio
var width = canvas.width;
var height = ( width / img.width ) * img.height;

//Draw scale image (This results in a squished height, despite "height" being correct)
context.drawImage( image, 0, 0, img.width, img.height, 0, 0, width, height );
即使
height
是正确的(在控制台中选中),图像还是以更小的高度绘制到画布上

另外,当我检查
canvas.width/canvas.height
vs
img.width/img.height
的比率时,我得到:
.707234
vs
.707818
这非常接近,无法解释巨大的高度问题

为什么会发生这种情况?我该如何解决这个问题

编辑:在Chrome上,此精确代码正确显示。

变量比率=(宽度/img.width)*img.width;将使比率等于width,并且从img.width中学不到任何信息,因为您正在用相同的值取消除法和乘法。这将打乱高度计算,从而打乱绘制的图像

试着这样做:

var ratio = ( width / img.width );
你会得到画布和图像高度之间的真实比例。但我认为你无论如何都不想那样

您想要的是保持图像的纵横比(宽度/高度)不变,并将其缩小以适合。即使画布在侧面或顶部和底部留下未使用的空间而具有不同的纵横比,这也是可能的

所以你真正需要知道的是你应该用哪个来缩放你的图像。宽度或高度

如果图像的纵横比大于画布,则使用宽度进行缩放。这意味着使宽度相同,并将高度设置为任何保持图像纵横比的值。这将在顶部和/或底部留下空白

如果图像的纵横比低于画布,则使用高度进行缩放。高度一样。刻度宽度。两边都是空白

var imgRatio = img.width / img.height;
var canRatio = canvas.width / canvas.height;

var scaledWidth = img.width * (canvas.height / img.height);
var scaledHeight = img.height * (canvas.width / img.height);

if (imgRatio > canRatio) {
    context.drawImage( image, 0, 0, canvas.width, scaledHeight );
} else {
    context.drawImage( image, 0, 0, scaledWidth, canvas.height );
}
另外,如果您没有对图像进行任何剪裁,只进行缩放,那么这些参数就是您所需要的


这是iOS Safari中的一个bug。这里描述的是:

解决方案如下:

问题

如果您的图像分辨率非常高(大于1024x1024),则将对其进行二次采样(将像素数减少16倍)。执行此操作时,Safari会引入一个错误,导致垂直高度过小

解决方案


要解决这个问题,您需要将图像分成小块(比如将文件分块读入缓冲区),调整垂直高度差,将它们绘制到临时画布上,然后将临时画布的像素绘制到目标画布上。

这有什么意义:var ratio=(width/img.width)*img.width@它能给出缩放高度(x/y)*y就是x。只要y不是零,它就不会改变任何东西。我认为这不是你想要的。@CandiedOrange请看我对你答案的评论。我错误地复制了我的代码,但发现另一篇文章有真正的错误。抱歉,我错误地复制了我的代码。我在上面把它修好了。这是iOS Safari中的一个错误: