问题描述
HTML5 Canvas 没有明确设置单个像素的方法.
The HTML5 Canvas has no method for explicitly setting a single pixel.
可能可以使用非常短的线设置像素,但是抗锯齿和线帽可能会干扰.
It might be possible to set a pixel using a very short line, but then antialising and line caps might interfere.
另一种方法可能是创建一个小的 ImageData
对象并使用:
Another way might be to create a small ImageData
object and using:
context.putImageData(data, x, y)
将其放置到位.
谁能描述一种有效且可靠的方法来做到这一点?
Can anyone describe an efficient and reliable way of doing this?
推荐答案
有两个最佳竞争者:
创建一个1×1的图片数据,设置颜色,
putImageData
在位置:
var id = myContext.createImageData(1,1); // only do this once per page
var d = id.data; // only do this once per page
d[0] = r;
d[1] = g;
d[2] = b;
d[3] = a;
myContext.putImageData( id, x, y );
使用fillRect()
绘制一个像素(应该没有走样问题):
Use fillRect()
to draw a pixel (there should be no aliasing issues):
ctx.fillStyle = "rgba("+r+","+g+","+b+","+(a/255)+")";
ctx.fillRect( x, y, 1, 1 );
你可以在这里测试这些速度:http://jsperf.com/setting-canvas-pixel/9 或这里 https://www.measurethat.net/Benchmarks/Show/1664/1
You can test the speed of these here: http://jsperf.com/setting-canvas-pixel/9 or here https://www.measurethat.net/Benchmarks/Show/1664/1
我建议针对您关心的浏览器进行测试以获得最大速度.截至 2017 年 7 月,fillRect()
在 Firefox v54 和 Chrome v59 上的速度提高了 5-6 倍(Win7x64).
I recommend testing against browsers you care about for maximum speed. As of July 2017, fillRect()
is 5-6× faster on Firefox v54 and Chrome v59 (Win7x64).
其他更愚蠢的选择是:
在整个画布上使用
getImageData()/putImageData()
;这比其他选项慢了大约 100 倍.
using
getImageData()/putImageData()
on the entire canvas; this is about 100× slower than other options.
使用数据 url 创建自定义图像并使用 drawImage()
显示它:
creating a custom image using a data url and using drawImage()
to show it:
var img = new Image;
img.src = "data:image/png;base64," + myPNGEncoder(r,g,b,a);
// Writing the PNGEncoder is left as an exercise for the reader
创建另一个 img 或画布,其中填充了您想要的所有像素,然后使用 drawImage()
仅对您想要的像素进行 blit.这可能会非常快,但有一个限制,即您需要预先计算所需的像素.
creating another img or canvas filled with all the pixels you want and use drawImage()
to blit just the pixel you want across. This would probably be very fast, but has the limitation that you need to pre-calculate the pixels you need.
请注意,我的测试不会尝试保存和恢复画布上下文fillStyle
;这会降低 fillRect()
的性能.另请注意,我并没有从头开始,也没有为每个测试测试完全相同的像素集.
Note that my tests do not attempt to save and restore the canvas context fillStyle
; this would slow down the fillRect()
performance. Also note that I am not starting with a clean slate or testing the exact same set of pixels for each test.
这篇关于在 HTML5 画布中设置单个像素的最佳方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!