Android byte [] для изображения в Camera.onPreviewFrame

При попытке преобразовать byte[] из Camera.onPreviewFrame в Bitamp с помощью BitmapFactory.decodeByteArray дает мне ошибку SkImageDecoder::Factory returned null

Ниже приведен мой код:

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

Ответы

Ответ 1

Я нашел ответ после долгого времени. Вот оно...

Вместо использования BitmapFactory я использовал свой собственный метод для декодирования этого byte[] data до допустимого формата изображения. Чтобы декодировать изображение до допустимого формата изображения, нужно знать, какой формат изображения используется камерой, вызывая camera.getParameters().getPictureFormat(). Это возвращает константу, определенную ImageFormat. Узнав формат, используйте кодировщик для кодирования изображения.

В моем случае byte[] data находился в формате YUV, поэтому я искал преобразование YUV в BMP, и это решило мою проблему.

Ответ 2

Это трудно найти! Но поскольку API 8, в android.graphics есть класс YuvImage. Это не образ потомка, поэтому все, что вы можете с ним сделать, это сохранить его в Jpeg, но вы можете сохранить его в потоке памяти, а затем загрузите в Bitmap Image, если это вам нужно.

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();
    }
}

Ответ 3

Начиная с Android 3.0 вы можете использовать TextureView и TextureSurface для отображения камеры, а затем использовать mTextureView.getBitmap() для получения дружественного кадра предварительного просмотра RGB.

Очень скелетный пример того, как это сделать, приведен в документах TextureView. Обратите внимание, что вам нужно будет настроить ваше приложение или активность на аппаратное ускорение, поместив android:hardwareAccelerated="true" в манифест.

Ответ 4

вы можете попробовать следующее: В этом примере отправьте кадры камеры на сервер

 @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();
}