javascript - 使用 Canvas 缩放图像而不使其模糊

标签 javascript html canvas html5-canvas

我有一个名为Engine.Renderer的类。它只是创建一个新的 Canvas ,让我可以轻松更新和渲染事件 Canvas 的场景。创建新 Canvas 时,我将这些设置应用到其上下文:

this.context.imageSmoothingEnabled       = false;
this.context.mozImageSmoothingEnabled    = false;
this.context.webkitImageSmoothingEnabled = false;

在 CSS 中,我添加了这些行:

main canvas {
    position: absolute;
    top: 0;

    image-rendering: optimizeSpeed;
    image-rendering: -moz-crisp-edges;
    image-rendering: -webkit-optimize-contrast;
    image-rendering: optimize-contrast;
    -ms-interpolation-mode: nearest-neighbor
}

我还编写了一个将 Canvas 调整为窗口的函数:

[...]
resize: function () {
    var width  = window.innerWidth;
    var height = width / 16 * 9;

    if ( height > window.innerHeight ) {
        height = window.innerHeight;
        width  = height * 16 / 9;
    }

    if ( width > window.innerWidth ) {
        width  = window.innerWidth;
        height = width / 16 * 9;
    }

    width  = Number( width ).toFixed();
    height = Number( height ).toFixed();

    this.canvas.style.width  = width  + "px";
    this.canvas.style.height = height + "px";

    this.container.style.width  = width  + "px";
    this.container.style.height = height + "px";
    this.container.style.left   = ( ( window.innerWidth - width ) / 2 ) + "px";

    // the new scale
    this.scale = ( width / this.canvas.width ).toFixed( 2 );
}
[...]

现在,我有一个名为 Character 的类。该类能够在给定的 Canvas 上创建和渲染新 Angular 色。渲染部分如下所示:

context.drawImage(
    this.outfit,

    this.sprite    * this.dimension.width,
    this.direction * this.dimension.height,

    this.dimension.width,
    this.dimension.height,

    this.position.x,
    this.position.y,

    // set the character sizes to normal size * scale
    this.dimension.width  * this.renderer.scale,
    this.dimension.height * this.renderer.scale
);

我有两个问题:

  1. 游戏性能比以前更差(在 ~1400x800px Canvas 上渲染单个 Angular 色时约为 9 FPS);
  2. 人物图像不像以前那么模糊,但我仍然可以看到一点模糊;

如何解决这些问题?

最佳答案

尝试使用整数值来表示位置和大小:

context.drawImage(
    this.outfit,

    this.sprite    * this.dimension.width,
    this.direction * this.dimension.height,

    this.dimension.width,
    this.dimension.height,

    this.position.x|0,          // make these integer
    this.position.y|0,

    // set the character sizes to normal size * scale
    (this.dimension.width  * this.renderer.scale)|0,
    (this.dimension.height * this.renderer.scale)|0
);

此外,使用 CSS/style 设置 Canvas 大小会影响插值。根据我自己的测试,插值的 CSS 设置似乎不再影响 Canvas 内容。

如果您需要放大固定的小尺寸,最好正确设置 Canvas 尺寸,然后使用缩放变换(或缩放值)来绘制内容:

this.canvas.width  = width;
this.canvas.height = height;

更新:基于评论 -

更改 Canvas 元素的大小时,状态也会重置,这意味着需要重新应用图像平滑设置。

禁用图像平滑时,浏览器将使用最近邻,这意味着缩放 2^n(2x、4x、8x 或 0.5x、0.25x 等)时会获得最佳结果,否则可能会显示“笨拙”。

一个<强> modified fiddle here

关于javascript - 使用 Canvas 缩放图像而不使其模糊,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23271093/

相关文章:

javascript 如何关闭 chrome 窗口而不发出警报?

javascript - 页面加载太慢 Jquery 和外部亚马逊图片文件

html - 数据 URI 哈希参数(隐藏数据 URI 的 PDF 工具栏)

javascript - 双击 Canvas 上删除点

javascript - 获取 Javascript 函数名称

javascript - 如何使用 Nodejs 对远程 Mongodb 进行 CRUD 操作

javascript - 触摸事件初始坐标

javascript - 将视频添加到 konvajs 舞台

javascript - 在函数内部调用函数

php - 如何在结果前显示php搜索引擎执行时间和结果数