1

カメラ ビューを実行している surfaceView から画像を取得しようとしています。

私はすでに onPreviewFrame を実装しており、デバッグが示すように正しく呼び出されています。

私が今直面している問題は、メソッドで受け取った byte[] データが YUV 空間色 (NV21) であるためです。それをグレースケールに変換してビットマップを生成し、それをファイルに保存しようとしています。 .

私が従っている変換プロセスは次のとおりです。

 public Bitmap convertYuvGrayScaleRGB(byte[] yuv, int width, int height) {

    int[] pixels = new int[width * height];

    for (int i = 0; i < height*width; i++) {
        int grey = yuv[i] & 0xff;
        pixels[i] = 0xFF000000 | (grey * 0x00010101);
    }

    return Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888);

  }

ファイルに保存するためのインポート手順は次のとおりです。

Bitmap bitmap = convertYuvGrayScaleRGB(data,widht,heigth);

    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG, 50, bytes);

        File f = new File(Environment.getExternalStorageDirectory()
                                    + File.separator + "test.jpg");

    Log.d("Camera", "File: " + f.getAbsolutePath());
    try {
        f.createNewFile();
        FileOutputStream fo = new FileOutputStream(f);
        fo.write(bytes.toByteArray());
        fo.close();
        bitmap.recycle();
        bitmap = null;
         } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();

とはいえ、私が得た結果は次のとおりです。

結果

4

4 に答える 4

0

S3でこの問題が発生しました。私の問題は、プレビューに間違った寸法を使用したことです。カメラは 16:9 だと思っていましたが、実際は 4:3 でした。

Camera.getParameters().getPreviewSize() を使用して、出力の内容を確認します。

于 2013-06-02T05:01:19.873 に答える
0

おそらく、変換している画像の幅は偶数ではありません。その場合、メモリにパディングされます。

ドキュメントを見てみましょう...

これよりも複雑なようです。コードをそのまま動作させたい場合は、幅を 16 の倍数にする必要があります。

ドキュメントから:

public static final int YV12

API レベル 9 の Android YUV 形式で追加されました。

この形式は、ソフトウェア デコーダーおよびアプリケーションに公開されます。

YV12 は、(W/2) x (H/2) Cr および Cb プレーンが続く WxH Y プレーンで構成される 4:2:0 YCrCb 平面フォーマットです。

この形式は、

偶数幅 偶数高さ 水平ストライド 16 ピクセルの倍数 高さに等しい垂直ストライド y_size = ストライド * 高さ c_stride = ALIGN(stride/2, 16) = y_size cb_offset = y_size + c_size

于 2013-05-26T18:13:35.320 に答える
0

私はこれを作りました:

int frameSize = width * height;
for (int i = 0; i < height; i++) {
    for (int j = 0; j < width; j++) {
        ret[frameSize + (i >> 1) * width + (j & ~1) + 1] = 127; //U
        ret[frameSize + (i >> 1) * width + (j & ~1) + 0] = 127; //V
    }
}

とてもシンプルですが、それは本当にうまく機能します;)

于 2013-12-16T11:17:36.267 に答える