英文:
Issue when drawing image on canvas on iPad
问题
我正在进行一个HTML5项目,它将在iPad上的WKWebView中运行。
我一切都是通过编程来完成的。
我的WKWebView框架占满整个屏幕,视口大小为1180x820,
所以我将我的画布尺寸和高度设置为1180x820。
但当我使用drawImage函数在我的画布上显示一个1920x1080的图像时,
图像不适合屏幕(显然),但显示得非常清晰(不模糊)。
_canvasContext.drawImage(imgMenu, 0, 0, 1920, 1080);
所以我在绘制图像时对图像进行了重新缩放,仍然使用drawImage函数。
_canvasContext.drawImage(imgMenu, 0, 0, 1920/2, 1080/2);
图像适合屏幕,但模糊。
缩小的质量真的很差(它真的可以更好,这个例子不是最糟糕的)。
我已经尝试了以下参数
_canvasContext.imageSmoothingEnabled = true;
_canvasContext.webkitImageSmoothingEnabled = true;
_canvasContext.mozImageSmoothingEnabled = true;
_canvasContext.imageSmoothingQuality = "high";
但没有帮助。
也许我做错了什么,我不明白该怎么做。
我的iPad屏幕分辨率为2360x1640,因此显示一个1920x1080的图片不应该是问题。
如果有人能帮助我,那将拯救我的生命
最诚挚的问候,
Alex
英文:
I'm working on an HTML5 project, that will run in a WKWebView on iPad.
I'm doing everything programatically.
My WKWebView frame takes the full screen, viewport is 1180x820,
so I set my canvas size and height to 1180x820 too.
Here is my original picture I'd like to display:
But when I'm displaying an 1920x1080 image on my canvas with the drawImage function,
the image does not fit on the screen (obsviously) but is really well displayed (not blurred).
_canvasContext.drawImage(imgMenu,0,0,1920,1080).
So I rescale the image when drawing it, still with the drawImage function.
_canvasContext
.drawImage(imgMenu,0,0,1920/2,1080/2)
The image fits in the screen, but is blurred.
The downscaling is really really bad (it really could be better, this example is not the worst one).
I already tried the parameters
_canvasContext.imageSmoothingEnabled = true;
_canvasContext.webkitImageSmoothingEnabled = true;
_canvasContext.mozImageSmoothingEnabled = true;
_canvasContext.imageSmoothingQuality = "high";
It does not help.
Maybe I do something wrong, I don't understand what to do.
Screen resolution of my ipad is 2360x1640, so displaying a 1920x1080 picture should not be a problem.
If anyone could help me, that would save my life
Best regards,
Alex
答案1
得分: 0
这是有关画布的那些令人讨厌和令人困惑的事情之一。你需要做的是使用devicePixelRatio
调整画布的大小。这将增加画布的实际大小,以匹配设备的像素密度。这可以是2,也可以是1.5等…… 视网膜屏幕通常是2。
绘制图像的聪明方式是支持任何图像大小并将其适应到画布区域(通常是缩小)。对于小图像,此代码将放大并失去分辨率。
在代码片段中的注释中提到的,如果你希望画布始终使用1180x820,请确保更改宽度和高度变量:
const width = 1180;
const height = 820;
对于片段的目的,我使用了窗口大小。如果您希望支持其他设备大小,这可能更适合您。
英文:
This is one of those annoying and confusing things about canvas. What you need to do is size the canvas using devicePixelRatio
. This will increase the actual size of the canvas to match the pixel density of the device. This could be 2, or 1.5 etc... a retina screen is often 2.
For drawing your image, the smart way is to support any image size and fit it into the canvas area (usually scaling down). With a tiny image, this code will scale up and lose resolution.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const IMAGE_URL = 'https://unsplash.it/1920/1080';
const canvas = document.createElement('canvas');
const _canvasContext = canvas.getContext('2d');
// you will probably want this, unless you want to support many screen sizes in which case you will actually want the window size:
/*
const width = 1180;
const height = 820;
*/
const width = window.innerWidth
const height = window.innerHeight
const ratio = window.devicePixelRatio;
// size the canvas to use pixel ratio
canvas.width = Math.round(width * ratio);
canvas.height = Math.round(height * ratio);
// downsize the canvas with css - making it
// retina compatible
canvas.style.width = width + 'px';
canvas.style.height = height + 'px';
document.body.appendChild(canvas);
_canvasContext.fillStyle = 'gray'
_canvasContext.fillRect(0, 0, canvas.width, canvas.height);
function drawImage(url) {
const img = new Image()
img.addEventListener('load', () => {
// find a good scale value to fit the image
// on the canvas
const scale = Math.min(
canvas.width / img.width,
canvas.height / img.height
);
// calculate image size and padding
const scaledWidth = img.width * scale;
const scaledHeight = img.height * scale;
const padX = scaledWidth < canvas.width ? canvas.width - scaledWidth : 0;
const padY = scaledHeight < canvas.height ? canvas.height - scaledHeight : 0;
_canvasContext.drawImage(img, padX / 2, padY / 2, scaledWidth, scaledHeight);
})
img.src = url;
}
drawImage(IMAGE_URL);
<!-- language: lang-css -->
body,html {
margin: 0;
padding: 0;
}
<!-- end snippet -->
As mentioned in a comment in the code snippet. If your want your canvas to always use 1180x820... be sure to change the width and height variables:
const width = 1180;
const height = 820;
For the purposes of the snippet I used the window size. Which may be better for you if you wish to support other device sizes.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论