4

我的问题:我有一个 ImageObject,用于创建 PatternObject。我的问题是,我在创建模式之前更改了图像的widthheight属性,但这实际上并没有重新映射图像(这也没有问题)。问题是,我现在有一个图案,它的大小(原始图像大小)与图像本身不同。如果我想用该图案的 fillStyle 画一条线,它不适合(因为我需要新尺寸的图案)。

我的问题:有没有一种简单的方法可以调整图案的宽度和高度?

我的尝试以及为什么我不喜欢它们:

1)将原始图像渲染到具有新尺寸的画布上并从中创建图案。没有使用这个,因为创建和渲染画布太慢导致无法直接加载图案。但我直接想要那个模式

2)计算新图像尺寸与原始图像尺寸的差异,改变上下文的线宽,使图案高度完全适合,并缩小线条,使其尺寸合适。没有使用它,因为我是实时渲染的,这太慢了,以后无法在 webapps 中使用。

4

1 回答 1

8

使用画布(您的第 1 步)是最灵活的方式。

使用画布在另一个画布上绘图并不比直接使用图像慢。它们都使用相同的元素基础(您正在像处理图像一样对位图进行位图传输)。

更新:在较新的浏览器中,使用模式作为样式进行绘制确实需要对模式进行局部转换矩阵的额外步骤。)

以图案大小创建一个新画布,然后将图像简单地绘制到其中:

patternCtx.drawImage(img, 0, 0, patternWidth, patternHeight);

然后使用 patternCtx 的画布作为模式的基础(在第一次绘制时,模式在内部缓存此图像,如果可能的话,它只是将其拥有的内容加倍,直到整个画布被填满)。

另一种选择是将图像预缩放为您需要的所有尺寸,将它们全部加载,然后选择您需要的尺寸的图像。

三是自己绘制图像作为图案。然而,与内置方法相比,这不是那么有效,尽管使用上述方法(内部)您可以获得可用的结果。

手动模式示例:

var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = function() {
  fillPattern(this, 64, 64);
  change.onchange = change.oninput = function() {
    fillPattern(img, this.value, this.value);
  }
};
img.src = "//i.stack.imgur.com/tkBVh.png";

// Fills canvas with image as pattern at size w,h
function fillPattern(img, w, h) {

    //draw once
    ctx.drawImage(img, 0, 0, w, h);

    while (w < canvas.width) {
        ctx.drawImage(canvas, w, 0);
        w <<= 1;  // shift left 1 = *2 but slightly faster
    }
    while (h < canvas.height) {
        ctx.drawImage(canvas, 0, h);
        h <<= 1;
    }
}
<input id=change type=range min=8 max=120 value=64><br>
<canvas id=canvas width=500 height=400></canvas>

(或以视频为模式)。

于 2013-06-22T03:21:31.147 回答