4

私はhtml5キャンバスを使用してレンダリングと画像を作成し、 getImageData(0 関数を使用してピクセルを読み取っていくつかの作業を行うよりも、画像の基本的な編集を行います。ソース画像のビット深度に関係なく、気づきました(8 ビット、16 ビット、24 ビット) getImageData() メソッドでは 8 ビット (256 色) を返すことができます。これは望ましくありません。getImageData(0 メソッドで、受け取った色と同じ数の色を吐き出すようにしたいと思います。

私はドキュメントを読みましたが、キャンバスはあなたが投げたビット深度を(比喩的に)処理できるはずですが、ビット深度を高く設定する場所がどこにもありません

4

2 に答える 2

7

Canvas は常に24 ビットデータ + 8 ビット アルファ チャネル (RGBA)を返します。もちろん、各コンポーネント値には 8 ビットまたは 256 の値があります。これは仕様によるものです。ただし、8 ビットのインデックス付き画像データは返されないため、8 ビット (インデックス付き) 画像データに遭遇した場合は、おそらくデータが間違っているか、オブジェクト/配列から読み取られている可能性があります。

仕様から:

画像データ . データ

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

反対の側面をカバーするために: PNG-8 や GIF などの 8 ビットのインデックス付きパレット画像を 2 ~ 256 色を使用して描画すると、インデックス付きパレットは常に RGBA バッファーに変換されます (実際には、ブラウザーによる読み込み時間であるため、これは canvas 自体が行うことではありません)。

キャンバスからデータを読み取るには、実際のピクセル配列ビューへの参照を含むさまざまな情報を含む画像データ オブジェクトの 2 つのレベル (より高度な用途では 3 つ) があります。

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

このオブジェクトから、デフォルトでビューであるピクセルのデータ ビューUint8ClampedArrayを取得します。

var pixelData = imageData.data;

さらに高度な使用法として、これから生のバイト バッファを取得できます (他のビュー、つまり 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 から始まります。

何らかの理由でパレットをインデックス付きパレットに減らす必要がある場合は、自分でアルゴリズムを提供する必要があります。シンプルで悪いものから、より複雑で正確なものまで、たくさんあります。しかし、これはキャンバスを使ってすぐにできることではありません。この回答でいくつかのポインターを見つけることができます。または、キャンバスから (アニメーション) GIF を作成するthis などのライブラリを使用することもできます。

また、キャンバスに描画された画像がクロスオリジン要件 (CORS) を満たしていない場合、キャンバスは (セキュリティ上) 「汚染」されgetImageData()、値が 0 に設定された配列が返されることにも注意してください。

于 2013-11-20T20:01:54.723 に答える
1

ImageData( によって返されるgetImageData) プロパティdataは、各エントリが実際の色ではなく、赤、緑、青、アルファの順番のカラー チャネルである配列を提供します。例えば

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);
于 2013-11-20T17:01:21.350 に答える