#java #android #android-camera2
#java #Android #android-camera2
Вопрос:
У меня проблема с API camera2 для Android. Моя конечная цель здесь — иметь массив байтов, который я могу редактировать с помощью opencv, одновременно отображая предварительный просмотр пользователю (например, OCR с предварительным просмотром). Я создал запрос на захват и добавил ImageReader в качестве цели. Затем в OnImageAvailableListener я получаю изображение, преобразую его в растровое изображение, а затем отображаю его в ImageView (и поворачиваю его).
Моя проблема в том, что через несколько секунд предварительный просмотр останавливается (после постепенного замедления) и в журнале om появляется следующая ошибка: E / BufferItemConsumer: [ImageReader-1225x1057f100m2-18869-0] Не удалось освободить буфер: неизвестная ошибка -1 (1)
Как вы можете видеть в моем коде, я уже пытался закрыть img после получения из него моего byte[] . Я также попытался очистить буфер. Я попытался закрыть ImageReader, но это, конечно, помешало мне получить какие-либо дополнительные изображения (выдает исключение).
Может кто-нибудь, пожалуйста, помочь мне понять, что я делаю не так? Я безрезультатно просматривал Google.
Это мой OnImageAvailableListener, дайте мне знать, если вам понадобится больше моего кода для помощи:
private final ImageReader.OnImageAvailableListener mOnImageAvailableListener
= new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image img = reader.acquireLatestImage();
final ImageView iv = findViewById(R.id.camPrev);
try{
if (img==null) throw new NullPointerException("null img");
ByteBuffer buffer = img.getPlanes()[0].getBuffer();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
final Bitmap b = BitmapFactory.decodeByteArray(data, 0, data.length);
runOnUiThread(new Runnable() {
@Override
public void run() {
iv.setImageBitmap(b);
iv.setRotation(90);
}
});
} catch (NullPointerException ex){
showToast("img is null");
}finally {
if(img!=null)
img.close();
}
}
};
Редактировать — добавление cameraStateCallback
private CameraDevice.StateCallback mCameraDeviceStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice cameraDevice) {
mCameraDevice = cameraDevice;
showToast("Connected to camera!");
createCameraPreviewSession();
}
@Override
public void onDisconnected(CameraDevice cameraDevice) {
closeCamera();
}
@Override
public void onError(CameraDevice cameraDevice, int i) {
closeCamera();
}
};
private void closeCamera() {
if (mCameraDevice != null) {
mCameraDevice.close();
mCameraDevice = null;
}
}
Комментарии:
1. Кажется, ваш код для этой части правильный, но можете ли вы изменить
buffer.remaining()
buffer.capacity()
и сообщить мне результаты? Я уже однажды реализовал camera2 и использовал емкость, насколько я помню.2. Также вы закрываете CameraDevice после достижения onPause () ?
3. Можете ли вы опубликовать свой код части stateCallBack?
4. Конечно, добавив обратный вызов состояния cameradevice вместе с closeCamera относительно onPause, я вызываю ту же функцию closeCamera вместе с stopBackgroundThread, которая должна позже выполнять саму обработку. Кстати, может быть, важно упомянуть, что я ОТКРЫВАЮ устройство камеры только на onWindowDocusChanged, а не на onResume или onCreate (поскольку я обнаружил, что оба они иногда пытаются загрузить, когда ImageView по-прежнему имеет значение null и не может выяснить, как создать какой-то прослушиватель состояния для ImageView (например, одинвид текстуры имеет)).
5. Я также пытался перейти на buffer.capacity, но, к сожалению, это не помогло..
Ответ №1:
Похоже, вы использовали setRepeatingRequest()
формат Jpeg. Это может не полностью поддерживаться на вашем устройстве, также зависит от выбранного вами разрешения изображения. Обычно мы используем createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
в этих случаях и получаем формат YUV или raw из ImageReader.
Я бы попытался выбрать низкое разрешение для Jpeg: возможно, этого будет достаточно, чтобы ImageReader продолжал работать.
Комментарии:
1. Спасибо. Дело в том, что я хочу, чтобы камера непрерывно передавала изображения в программу чтения изображений для создания обрабатываемого предварительного просмотра, пока не произойдет событие. Ответит ли ваше решение на эту потребность?
2. Так и должно быть. Что вы подразумеваете под словами обрабатываемый предварительный просмотр , я не совсем понимаю.
3. Допустим, я хочу получить изображение с камеры, перевести его в оттенки серого и только затем показать его на ImageView. Просто предварительно обработайте его перед отображением пользователю.
4. Если вы хотите преобразовать входные данные камеры в оттенки серого, YUV должен быть вашим выбором.
5. Есть несколько других шагов обработки, которые я хочу выполнить. Я протестирую ваше решение и обновлю. Спасибо!