私の問題は次のとおりです。Androidでカメラをセットアップし、onPreviewFrame-listenerを使用してプレビューデータを受信します。このリスナーは、デフォルトのAndroidYUV形式の画像データを含むbyte[]配列を渡します(デバイスはR5G6B5-をサポートしていません)。フォーマット)。各ピクセルは12ビットで構成されているため、少し注意が必要です。今私がやりたいのは、YUVデータをARGBデータに変換して画像処理を行うことです。これは、高いパフォーマンスを維持するために、renderscriptを使用して実行する必要があります。
私のアイデアは、1つの要素に2つのピクセル(24ビット= 3バイト)を渡してから、2つのARGBピクセルを返すことでした。問題は、Renderscriptではu8_3(3次元8ビットベクトル)が32ビットに格納されていることです。これは、最後の8ビットが未使用であることを意味します。ただし、イメージデータを割り当てにコピーすると、32ビットがすべて使用されるため、最後の8ビットが失われます。32ビットの入力データを使用したとしても、最後の8ビットはピクセルの2/3しかないため、役に立ちません。3バイト配列で構成される要素を定義する場合、実際のサイズは3バイトです。しかし、Allocation.copyFrom()メソッドはin-Allocationをデータで埋めず、byte[]で埋めるのに適切なデータ型を持っていないと主張します。
renderscriptのドキュメントには、APIレベル17で正確に実行する必要があるScriptIntrinsicYuvToRGBがあると記載されていますが、実際にはクラスは存在しません。APIレベル17はダウンロードできなくなったようですが、ダウンロードしました。誰かがそれについて何か情報を持っていますか?ScriptIntrinsicを試したことがある人はいますか?
結論として、私の質問は次のとおりです。カメラデータをARGBデータに高速に変換し、ハードウェアで高速化する方法は?
これがDalvikVMでそれを行う方法です(オンラインのどこかでコードが見つかりました、それは機能します):
@SuppressWarnings("unused")
private void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) {
final int frameSize = width * height;
for (int j = 0, yp = 0; j < height; j++) {
int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
for (int i = 0; i < width; i++, yp++) {
int y = (0xff & ((int) yuv420sp[yp])) - 16;
if (y < 0)
y = 0;
if ((i & 1) == 0) {
v = (0xff & yuv420sp[uvp++]) - 128;
u = (0xff & yuv420sp[uvp++]) - 128;
}
int y1192 = 1192 * y;
int r = (y1192 + 1634 * v);
int g = (y1192 - 833 * v - 400 * u);
int b = (y1192 + 2066 * u);
if (r < 0)
r = 0;
else if (r > 262143)
r = 262143;
if (g < 0)
g = 0;
else if (g > 262143)
g = 262143;
if (b < 0)
b = 0;
else if (b > 262143)
b = 262143;
rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
}
}
}