web-dev-qa-db-ja.com

Android byte [] to image in Camera.onPreviewFrame

byte[]を使用してCamera.onPreviewFrameBitmapFactory.decodeByteArrayBitampに変換しようとすると、エラーSkImageDecoder::Factory returned nullが表示されます。

以下は私のコードです:

public void onPreviewFrame(byte[] data, Camera camera) {
    Bitmap bmp=BitmapFactory.decodeByteArray(data, 0, data.length);
}
16
Vinod Maurya

久しぶりに答えを見つけました。ここにあります...

BitmapFactoryを使用する代わりに、カスタムメソッドを使用してこの_byte[] data_を有効な画像形式にデコードしました。画像を有効な画像形式にデコードするには、 camera.getParameters().getPictureFormat() を呼び出して、カメラで使用されている画像形式を知る必要があります。これは、 ImageFormat で定義される定数を返します。フォーマットを知ったら、適切なエンコーダーを使用して画像をエンコードします。

私の場合、_byte[] data_はYUV形式だったので、YUVからBMPへの変換を探しましたが、これで問題は解決しました。

4
Vinod Maurya

これは見つけるのが難しいです!ただし、API 8以降、Android.graphicsにはYuvImageクラスがあります。これはイメージの子孫ではないため、Jpegに保存するだけですが、必要に応じてメモリストリームに保存してから、ビットマップイメージにロードすることもできます。

import Android.graphics.YuvImage;

@Override
public void onPreviewFrame(byte[] data, Camera camera) {
    try {
        Camera.Parameters parameters = camera.getParameters();
        Size size = parameters.getPreviewSize();
        YuvImage image = new YuvImage(data, parameters.getPreviewFormat(),
                size.width, size.height, null);
        File file = new File(Environment.getExternalStorageDirectory()
                .getPath() + "/out.jpg");
        FileOutputStream filecon = new FileOutputStream(file);
        image.compressToJpeg(
                new Rect(0, 0, image.getWidth(), image.getHeight()), 90,
                filecon);
    } catch (FileNotFoundException e) {
        Toast toast = Toast
                .makeText(getBaseContext(), e.getMessage(), 1000);
        toast.show();
    }
}
32
weston

Android 3.0以降、TextureViewTextureSurfaceを使用してカメラを表示し、mTextureView.getBitmap()を使用してわかりやすいRGBプレビューを取得できますフレーム。

これを行う方法の非常に骨格的な例は、 TextureView docs にあります。マニフェストにAndroid:hardwareAccelerated="true"を入力して、アプリケーションまたはアクティビティをハードウェアアクセラレーションに設定する必要があることに注意してください。

7
Timmmm

これを試すことができます:この例では、カメラフレームをサーバーに送信します

 @Override
        public void onPreviewFrame(byte[] data, Camera camera) {
        try {
            byte[] baos = convertYuvToJpeg(data, camera);
            StringBuilder dataBuilder = new StringBuilder();
            dataBuilder.append("data:image/jpeg;base64,").append(Base64.encodeToString(baos, Base64.DEFAULT));
            mSocket.emit("newFrame", dataBuilder.toString());
        } catch (Exception e) {
           Log.d("########", "ERROR");
        }
    }

};


public byte[] convertYuvToJpeg(byte[] data, Camera camera) {

    YuvImage image = new YuvImage(data, ImageFormat.NV21,
            camera.getParameters().getPreviewSize().width, camera.getParameters().getPreviewSize().height, null);

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    int quality = 20; //set quality
    image.compressToJpeg(new Rect(0, 0, camera.getParameters().getPreviewSize().width, camera.getParameters().getPreviewSize().height), quality, baos);//this line decreases the image quality


    return baos.toByteArray();
}
2
vrbsm