在iOS Safari中缩放和绘制图像到画布时,宽度是正确的,但高度被压扁了

When scaling and drawing an image to canvas in iOS Safari, width is correct but height is squished

本文关键字:高度 缩放 Safari 绘制 图像 布时 iOS      更新时间:2023-09-26

我正在加载图像,然后将该图像绘制到画布上。我还缩小了图像以适合画布。当我这样做时,图像以适当的宽度绘制到画布上,但高度约为画布实际高度的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.heightimg.width / img.height的比例时,我得到:.707234 vs .707818 .这是如此接近,它不能解释巨大的高度问题。

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

EDIT:在Chrome上,这个确切的代码显示正确。

var ratio = (width/img。宽度)*图像宽度;将使比率等于宽度,没有从img中学到任何东西。宽度,因为你是用相同的值相乘来撤销除法。这将打乱你的高度计算,从而打乱绘制的图像。

试着这样写:

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

如果你没有对图像进行任何剪辑,只是缩放,那么这些参数就是你所需要的。

http://www.w3schools.com/tags/canvas_drawimage.asp

这是iOS Safari中的一个bug。说明如下:Mobile Safari渲染在画布上缩放?

解决方案在这里:https://github.com/stomita/ios-imagefile-megapixel

如果你有一个非常高分辨率的图像(大于1024x1024),它将被抽样(减少16倍的像素数)。当这样做时,Safari会引入一个错误,导致垂直高度过小。

<<p> 解决方案/strong>

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