猿问

Canvas drawImage在拉伸时绘制不需要的像素

我使用 drawImage 将 1x2 像素精灵拉伸为 300x2 水平线。

这曾经工作得很好,但最近我注意到 Chrome、Firefox 和 Edge 上有一个问题,drawImage 函数将开始包含 1x2 定义框之外的精灵数据。(顺便说一句,这不会发生在移动设备上)

在下面的链接中,绘制线条对于小长度来说效果很好,但是一旦长度超过 255 像素,它将开始绘制不需要的颜色(蓝色)。

JSFiddle;https://jsfiddle.net/y6bo1zfu/1/

任何人都知道这可能是什么原因造成的?这可能是一个已知的错误还是通过优化添加的意外功能?

尝试将图像拉伸为其默认宽度 256 倍是禁忌吗?


梦里花落0921
浏览 83回答 1
1回答

慕盖茨4494581

这是由硬件加速 (HWA)(即 GPU)引起的。您可以在自己的浏览器上禁用它,您会看到它会按预期工作。遗憾的是,您无法要求所有用户禁用 HWA。解决这个问题的一种简单方法是创建一个仅包含图像所需部分的 ImageBitmap。这非常简单,因为该createImageBitmap()方法接受 5 个参数版本createImageBitmap( source, sourceX, sourceY, sourceWidth, sourceHeight );并且drawImage()接受 5 参数版本drawImage( source, destinationX, destinationY, destinationWidth, destinationHeight );因此,您可以将 9 个参数版本重写drawImage()为drawImage(   await createImageBitmap( source, sourceX, sourceY, sourceWidth, sourceHeight ),  destinationX, destinationY, destinationWidth, destinationHeight)var rawImage = false;var testCanvas = document.createElement('canvas');testCanvas.width = 300;testCanvas.height = 20;var testContext = testCanvas.getContext("2d");testContext.imageSmoothingEnabled = false;document.body.appendChild( testCanvas );function loadImage(){  rawImage = new Image();  rawImage.onload = function(){    // Create the sprite image    createSpriteImage();        document.body.appendChild( rawImage );  }  rawImage.src = "data:image/png;base64,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";}async function createSpriteImage(){  testContext.drawImage(    await createImageBitmap(rawImage,      2,     // Source X for this part of the Sprite      1 ,    // Source Y for this part of the Sprite      1 ,    // Width of this part of the Sprite      2      // Height of this part of the Sprite    ),    0,        // The X position where to draw    0,        // The Y position where to draw    300 ,     // Width of the line    2      // Height of the line  );    testContext.drawImage(    await createImageBitmap(rawImage,      2,    // Source X for this part of the Sprite      1 ,   // Source Y for this part of the Sprite      1 ,   // Width of this part of the Sprite      2     // Height of this part of the Sprite    ) ,      0 ,       // The X position where to draw    3 ,       // The Y position where to draw    298 ,     // Width of the line    2    // Height of the line  );    testContext.drawImage(    await createImageBitmap(rawImage,      2,    // Source X for this part of the Sprite      1 ,   // Source Y for this part of the Sprite      1 ,   // Width of this part of the Sprite      2     // Height of this part of the Sprite    ) ,    0,        // The X position where to draw    6,        // The Y position where to draw    264 ,     // Width of the line    2         // Height of the line  );    testContext.drawImage(    await createImageBitmap(rawImage,      2,    // Source X for this part of the Sprite      1 ,   // Source Y for this part of the Sprite      1 ,   // Width of this part of the Sprite      2     // Height of this part of the Sprite    ),    0,        // The X position where to draw    9,        // The Y position where to draw    256 ,     // Width of the line    2         // Height of the line  );    testContext.drawImage(    await createImageBitmap(rawImage,      2,     // Source X for this part of the Sprite      1 ,    // Source Y for this part of the Sprite      1 ,    // Width of this part of the Sprite      2      // Height of this part of the Sprite    ),    0,       // The X position where to draw    12,      // The Y position where to draw    255 ,    // Width of the line    2 ,      // Height of the line  );    testContext.drawImage(    await createImageBitmap(rawImage,      2,     // Source X for this part of the Sprite      1 ,    // Source Y for this part of the Sprite      1 ,    // Width of this part of the Sprite      2      // Height of this part of the Sprite    ),    0,       // The X position where to draw    15,      // The Y position where to draw    100 ,    // Width of the line    2 ,      // Height of the line  );    testContext.drawImage(    await createImageBitmap(rawImage,      2,     // Source X for this part of the Sprite      1 ,    // Source Y for this part of the Sprite      1 ,    // Width of this part of the Sprite      2      // Height of this part of the Sprite    ),    0,       // The X position where to draw    18,      // The Y position where to draw    10 ,     // Width of the line    2 ,      // Height of the line  );}//loadImage();body,html {    margin: 0px;    background-color: #4f4f4f;}img{    display: block;    width: 50px;    height: 50px;    margin: 0px auto;  image-rendering: pixelated;}canvas{  display: block;    width: 300px;    height: 20px;    box-shadow: 1px 1px 4px black;    margin: 15px auto;    background-color: white;    border: 1px solid white;}而对于不支持 ImageBitmap 接口的浏览器,至少可以通过使用其他画布来对这种用法进行猴子修补。
随时随地看视频慕课网APP

相关分类

Html5
我要回答