更新:デバイスのベンダーに連絡したところ、平面の 4:2:0 YUV フル スケール ピクセル フォーマットを使用しているとのことでした。調べてみると、YUV 4:2:0 には I420、J420、YV12 の 3 つの主要なフォーマットがあるようです。私のコードを実行すると、Android YuvImage クラスにこの画像形式の定数があったため、興奮しましたが、次の例外が発生しました。
java.lang.IllegalArgumentException: only support ImageFormat.NV21 and ImageFormat.YUY2 for now
まあそれは残念です..
その後、YUV420 と NV21 の違いについて学びました。
NV21 ピクセル形式の画像に示すように、2 つのクロマ プレーンをインターリーブする単純な関数を作成しようとしました。
public static void convertYUY420ToNV21(byte[] data_yuv420, byte[] data_yuv_N21) {
int idx = (int) (data_yuv_N21.length * (2.0f / 3.0f));
int j = idx;
int chroma_plane_end = (int) (idx + ((data_yuv_N21.length - idx) / 2));
for (int i = idx; i < chroma_plane_end; i++) {
data_yuv_N21[j] = data_yuv420[i];
j += 2;
}
j = idx + 1;
for (int i = chroma_plane_end; i < data_yuv_N21.length; i++) {
data_yuv_N21[j] = data_yuv420[i];
j += 2;
}
ただし、結果は元のコードと同じようです。考えられた理由の 1 つは、バイト配列のサイズ (1843200) でした。YUV420 の場合、1 ピクセルの深さは 12 ビットであると読みました。カメラの解像度は 1280x720 で、921,600 ピクセルまたは 1,382,400 バイトです。これは、実際のバイト配列サイズよりも 3 分の 1 小さい値です。プレーン間にパディングがあるかもしれないと読みましたが、それを調べる方法に行き詰まっています。
YuvImage クラスのコンストラクターには strides パラメーターがありますが、Android 開発者向けドキュメントを読んでも使い方がわかりません。
手がかりはありますか?
元の投稿:
次の問題があります: 使用されているカメラの種類や画像形式に関する情報が提供されていないデバイスのカメラにアクセスしようとしています。提供される唯一の情報は、ビデオ ストリーム出力を含むバイト配列を取得する方法です。しかし、解像度が 1280x720 で、バイト配列のサイズが 1843200 であることがわかりました。グーグルで検索すると、YUYV および同様のピクセル形式を使用して、まったく同じサイズと寸法のカメラを見つけました。その知識に基づいて、以下のコードを書きました。
ByteArrayOutputStream out = new ByteArrayOutputStream();
YuvImage yuv = new YuvImage(data, ImageFormat.YUY2, 1280, 720, null);
yuv.compressToJpeg(new Rect(0, 0, 1280, 720), 100, out);
byte[] bytes = out.toByteArray();
bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
if (bitmap != null) {
ImageView cameraImageView = (ImageView) findViewById(R.id.imageView);
cameraImageView.setImageBitmap(bitmap);
}
BitmapFactory.decodeByteArray 関数は有効なビットマップを返しましたが、それを表示すると、画像に緑色の色合いと紫色の斑点が見られました。これはおそらくカラー チャネルに関連したものでしょうか? サンプル画像:
使用されている正確なピクセル形式/エンコーディングを見つける方法はありますか? これから他に何を試すべきかわかりません。アドバイスをいただければ幸いです。