在iPad上绘制画布上的图像时出现问题。

huangapple go评论63阅读模式
英文:

Issue when drawing image on canvas on iPad

问题

我正在进行一个HTML5项目,它将在iPad上的WKWebView中运行。
我一切都是通过编程来完成的。

我的WKWebView框架占满整个屏幕,视口大小为1180x820,
所以我将我的画布尺寸和高度设置为1180x820。

这是我想要显示的原始图片:
在iPad上绘制画布上的图像时出现问题。

但当我使用drawImage函数在我的画布上显示一个1920x1080的图像时,
图像不适合屏幕(显然),但显示得非常清晰(不模糊)。

_canvasContext.drawImage(imgMenu, 0, 0, 1920, 1080);

在iPad上绘制画布上的图像时出现问题。

所以我在绘制图像时对图像进行了重新缩放,仍然使用drawImage函数。

_canvasContext.drawImage(imgMenu, 0, 0, 1920/2, 1080/2);

在iPad上绘制画布上的图像时出现问题。

图像适合屏幕,但模糊。
缩小的质量真的很差(它真的可以更好,这个例子不是最糟糕的)。

我已经尝试了以下参数

_canvasContext.imageSmoothingEnabled = true;
_canvasContext.webkitImageSmoothingEnabled = true;
_canvasContext.mozImageSmoothingEnabled = true;
_canvasContext.imageSmoothingQuality = "high";

但没有帮助。

也许我做错了什么,我不明白该怎么做。

我的iPad屏幕分辨率为2360x1640,因此显示一个1920x1080的图片不应该是问题。

如果有人能帮助我,那将拯救我的生命 在iPad上绘制画布上的图像时出现问题。

最诚挚的问候,
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:
在iPad上绘制画布上的图像时出现问题。

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).

在iPad上绘制画布上的图像时出现问题。

So I rescale the image when drawing it, still with the drawImage function.
_canvasContext.drawImage(imgMenu,0,0,1920/2,1080/2)

在iPad上绘制画布上的图像时出现问题。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 在iPad上绘制画布上的图像时出现问题。

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 = &#39;https://unsplash.it/1920/1080&#39;;

const canvas = document.createElement(&#39;canvas&#39;);
const _canvasContext = canvas.getContext(&#39;2d&#39;);

// 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 + &#39;px&#39;;
canvas.style.height = height + &#39;px&#39;;

document.body.appendChild(canvas);
_canvasContext.fillStyle = &#39;gray&#39;
_canvasContext.fillRect(0, 0, canvas.width, canvas.height);

function drawImage(url) {
  const img = new Image()
  img.addEventListener(&#39;load&#39;, () =&gt; {

    // 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 &lt; canvas.width ? canvas.width - scaledWidth : 0;
    const padY = scaledHeight &lt; 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.

huangapple
  • 本文由 发表于 2023年2月8日 20:19:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/75385701.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定