2013-11-20 77 views
2

我使用html5 canvas来渲染图像,对图像进行一些基本编辑,而不是尝试使用getImageData(0函数来读取像素并做一些操作我注意到,无论源图像的位深度是多少(8位,16位,24位),getImageData()方法允许返回8位(256色),这是不可取的。 getImageData(0方法吐出尽可能多的颜色,因为它接收。html5 canvas在使用getImageData时总是返回8位颜色()

我已经通读文档和画布应该能够处理任何位深度,你扔在它(比喻),但我不能看到任何地方设置位深度更高

回答

5

帆布将总是返回24位数据+ 8位α通道(RGBA)。每个组件的值当然会有8位或256个值。这是每个规格。它永远不会返回8位索引图像数据,所以如果你以某种方式运行到8位(索引)图像数据,那么你可能读取的是错误的数据或来自对象/数组的数据。

specification

图象 - 。数据

Returns the one-dimensional array containing the data in RGBA order, 
as integers in the range 0 to 255. 

而只是为了覆盖相反方面:如果在8位索引调色板图像绘制诸如PNG-8或使用2 GIF - 256色的索引调色板将总是被转换到RGBA缓冲区(它实际上在加载时由浏览器转换为RGBA,所以这不是画布本身)。

要读取从画布数据你有两个级别(或三个为更高级的使用),其中包含各种信息,包括一个参考实际的像素阵列视图的图像数据对象:

var imageData = context.getImageData(x, y, w, h); 

从该对象我们得到数据视图为默认情况下是一个Uint8ClampedArray鉴于像素:

var pixelData = imageData.data; 

而对于更高级的用法,我们可以从中得到的原始字节的缓冲区(如果您将n提供其他意见,即。 Uint32Array)可从以下地址获得:

var rawBytes = pixelData.buffer; 
var buffer32 = new Uint32Array(rawBytes); 

但是让我们坚持到默认的8位夹视图 - 从中​​读取数据,你需要知道的是,像素总是打包成RGBA或32位值。所以我们可以通过做一个像素:

var r = pixelData[0]; 
var g = pixelData[1]; 
var b = pixelData[2]; 
var a = pixelData[3]; 

下一个像素将从索引4开始依此类推。

如果你由于某种原因需要减少调色板索引调色板,你将不得不提供这个算法。有许多从简单到糟糕到更复杂和准确的。但是这不是你可以用画布开箱即可完成的事情。一些指针可以在this answer中找到,或者您可以使用库such as this,它将从画布创建(动画)GIF。

另外请注意,如果绘制到画布中的图像不能满足交叉来源要求(CORS),则画布将“受污染”(安全方面),并且getImageData()将返回一个数组,其值设置为0.

+0

什么是“新Uint32Array'的一点?”?不是8位**已经是真实的字节吗? – Pacerier

+0

表现。您允许CPU每个周期读取32位而不是8x4。您可以对通常更快的值执行位移。同样,你可以使用掩码和AND/OR /等。操作。您可以简化以1:1基准为基准的坐标,而不是1:4 + 4 .. – K3N

+0

'Uint32Array'是否击败了'Int32Array'? – Pacerier

0

ImageData(由getImageData返回)属性data为您提供了一个数组,其中每个条目都是按红色,绿色,蓝色和alpha顺序排列的颜色通道,而不是实际的颜色。例如

red=imgData.data[0]; 
green=imgData.data[1]; 
blue=imgData.data[2]; 
alpha=imgData.data[3]; 
colour = '#' + (red<16)?'0':'' + red.toString(16) + 
(green<16)?'0':'' + green.toString(16) + 
(blue<16)?'0':'' + blue.toString(16); 
+0

是的,但是当我遍历所有的数据,并把每个(唯一)的颜色和数组,我总是得到256,无论图像的位深度 – QBM5

+0

@ QBM5你可以发布代码 – Musa