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