Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/96.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS平台上的HTML5画布缩放问题_Ios_Html_Canvas_Cordova_Scaling - Fatal编程技术网

iOS平台上的HTML5画布缩放问题

iOS平台上的HTML5画布缩放问题,ios,html,canvas,cordova,scaling,Ios,Html,Canvas,Cordova,Scaling,我一直在phonegap中开发一个项目,试图为Android和iOS构建。其主要思想是访问电话库中保存的图片,将该图片保存到HTML img元素,然后将该img元素绘制到画布上。从那里,用户可以缩放和旋转图像 我的安卓系统没有问题。我已经使用模拟器和设备进行了测试,并测试了大量设备(不同的像素比率、密度等),最终的画布转换总是能给出预期的结果 另一方面,iOS版本没有那么成功。缩放/旋转画布看起来很好,直到我将画布缩放到略大于其原始大小(大约比原始大小大4-5像素)为止。放大画布大小后,在画布上

我一直在phonegap中开发一个项目,试图为Android和iOS构建。其主要思想是访问电话库中保存的图片,将该图片保存到HTML img元素,然后将该img元素绘制到画布上。从那里,用户可以缩放和旋转图像

我的安卓系统没有问题。我已经使用模拟器和设备进行了测试,并测试了大量设备(不同的像素比率、密度等),最终的画布转换总是能给出预期的结果

另一方面,iOS版本没有那么成功。缩放/旋转画布看起来很好,直到我将画布缩放到略大于其原始大小(大约比原始大小大4-5像素)为止。放大画布大小后,在画布上绘制的图像会发生变化。我通常会在整个画布上绘制一小部分图像(通常是左上角),而不是现在看到显示的整个图像

我的html画布:

<canvas id="sourceImgCanvas" width="200" height="200" style="z-index:1; position:absolute; left:5%; top:100px;"></canvas>
为了缩放画布,我在画布的右下角有一个箭头。拖动时,它会记录距离画布左上角的距离,并根据距离设置画布的高度/宽度

//Calls when user is dragging the arrow resize button.  Updates the source image size
function ResizeSourceImage() {
    var horizontalDistanceFromTopLeft = parseFloat(ovalCanvas.style.left) + ovalCanvas.width - endX;
    var verticalDistanceFromTopLeft = parseFloat(ovalCanvas.style.top) + ovalCanvas.height - endY;

    //update canvas size with new length
    sourceImgCanvas.width = originalSrcImgWidth - horizontalDistanceFromTopLeft;
    sourceImgCanvas.height = originalSrcImgHeight - verticalDistanceFromTopLeft;

    //re-draw based on new size
    sourceImgContext.drawImage(sourceImg, 0, 0, pictureWidth * drawRatio * drawRatioMod, pictureHeight * drawRatio * drawRatioMod, 0, 0, sourceImgCanvas.width, sourceImgCanvas.height);
}
上面的drawRatio是我在重新调整图像大小时存储的比率(这里没有显示代码;它相当长,但很简单)

drawRatioMod
是我在实验时设置的一个值,也是我问题的主要焦点。在Android上,我设置了
drawRatioMod=1
,这样绘图就不会受到影响。在iPhone4/iPad(我可以使用的设备)上,我设置了
drawRatioMod=0.5
。这解决了我在iOS上使用html5画布时遇到的一些初始问题:因为iPhone4的分辨率实际上是屏幕大小的两倍,所以我将要绘制的源图像的长度/宽度减少了一半

每当用户移动调整大小箭头工具,从而更新画布大小时,就会调用上面的
ResizeSourceImage()
函数。只有当我缩小比例时,图像才能正确地调整到新的画布大小。如果我将画布放大超过5-6像素,画布将不再绘制整个源图像;相反,画布仅在整个画布上绘制图像的左上角

我已经处理这个问题好几天了,运气不好。我最初认为这与设备像素比率有关(可通过Javascript
窗口访问。devicePixelRatio
),但我在几个不同比率的Android设备上进行了测试,从未得到过这样的结果

我觉得我很快就能解决这个问题了,因为图像只有在iOS上放大时才会显示不正确。非常感谢您的指点/提示!我尝试了几次与
window.devicePixelRatio
相关的修复,但我的iPad的iPhone4模拟器总是返回1的像素比率(这似乎不正确),而我在这类修复中没有运气


干杯!(我试图发布有关画布缩放和绘制的基本代码。如果你想看到其他代码,我可以发布更多;我希望发布一篇与中国长城不同的帖子:)

经过几天的测试,我终于找到了罪魁祸首:使用
myContext.drawImage()
在iOS中,对图像进行切片是一件非常痛苦的事情(可能是因为视网膜显示,但我不是100%确定)

我所做的是将双缓冲和使用
myContext.drawImage()
进行缩放而不是切片相结合

FelineSoft在画布相关的几个方面发表了一篇很好的文章。这里解释了双缓冲:

因此,不要像这样对原始图像进行切片:

sourceImgContext.drawImage(sourceImg, 0, 0, pictureWidth * drawRatio * drawRatioMod, pictureHeight * drawRatio * drawRatioMod, 0, 0, sourceImgCanvas.width, sourceImgCanvas.height);
相反,我将图像绘制到缓冲区,然后将其绘制到用户在屏幕上看到的画布上。回顾过去,可能不需要缓冲区来解决我曾经遇到的这个缩放问题,但习惯于:

//buffer to draw the image to before drawing on-screen
var bufferCanvas = document.createElement('canvas');
var bufferContext = bufferCanvas.getContext('2d');

bufferContext.drawImage(sourceImg, 0, 0, bufferCanvas.width, bufferCanvas.height);

//later, I draw the image stored in buffer to a canvas user will see on-screen
//if this call is coming right after the command to draw image to buffer, would be best
//to add a check to make sure buffer has finished drawing image.
sourceImgContext.drawImage(bufferCanvas, 0, 0, sourceImgCanvas.width, sourceImgCanvas.height);
正如您所看到的,我不再使用
canvas.drawImage()
对源图像进行切片,我只是将其缩放以适合画布

看来我是走错了路,但希望其他遇到类似问题的人会发现这种方法很有帮助

//buffer to draw the image to before drawing on-screen
var bufferCanvas = document.createElement('canvas');
var bufferContext = bufferCanvas.getContext('2d');

bufferContext.drawImage(sourceImg, 0, 0, bufferCanvas.width, bufferCanvas.height);

//later, I draw the image stored in buffer to a canvas user will see on-screen
//if this call is coming right after the command to draw image to buffer, would be best
//to add a check to make sure buffer has finished drawing image.
sourceImgContext.drawImage(bufferCanvas, 0, 0, sourceImgCanvas.width, sourceImgCanvas.height);