Захват изображения без намерения, дает различный вывод на разных устройствах
Мое требование - ни показывать предварительный просмотр камеры, ни использовать намерение камеры для захвата изображения.
Там, где я нахожу способ, который работает для моего первого тестового устройства (вкладка Galaxy 7 ").
Моя CaptureImage
функция ниже
private void CaptureImage() {
int FrontCameraFound = getCameraID();
if (FrontCameraFound != -1) {
mCamera = Camera.open(FrontCameraFound);
parameters = mCamera.getParameters();
mCamera.setParameters(parameters);
mCamera.startPreview();
Camera.PictureCallback mCall = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
// set bitmap tp image view just to check
// if image capture proper, testing purpose
iv_image.setImageBitmap(bmp);
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
};
mCamera.takePicture(null, null, mCall);
}
}
и getCameraID
, как показано ниже
private int getCameraID() {
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
for (int camIdx = 0; camIdx < Camera.getNumberOfCameras(); camIdx++) {
Camera.getCameraInfo(camIdx, cameraInfo);
// for capture image from back camera
// If want to capture from front
// then change it to CAMERA_FACING_FRONT
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
try {
return camIdx;
} catch (RuntimeException e) {
}
}
}
return -1;
}
Теперь мне трудно выполнить успешную работу над кодом на разных устройствах.
- Samsung Galaxy S + (2.3.6): передняя камера всегда возвращает зеленое изображение, но кодирование камеры заднего обзора работает нормально.
- Samsung Galaxy Nexus (4.1): кодирование не работает. Ни для Front, ни для Back камеры и не дает "takePicture".
- LG Optimus Net (2.3.4): есть только камера заднего вида и работает нормально.
- Samsung Galaxy Tab 7 "(2.3.3): обе камеры работают нормально.
- Motorola Xoom (3.1): обе камеры работают нормально.
Logcat от Samsung Galaxy Nexus:
09-21 09:37:42.125: E/AndroidRuntime(4647): Caused by: java.lang.RuntimeException: takePicture failed
09-21 09:37:42.125: E/AndroidRuntime(4647): at android.hardware.Camera.native_takePicture(Native Method)
09-21 09:37:42.125: E/AndroidRuntime(4647): at android.hardware.Camera.takePicture(Camera.java:1061)
09-21 09:37:42.125: E/AndroidRuntime(4647): at android.hardware.Camera.takePicture(Camera.java:1006)
09-21 09:37:42.125: E/AndroidRuntime(4647): at fortyonepost.com.pwop.TakePictureDemoActivity.CaptureImage(TakePictureDemoActivity.java:63)
09-21 09:37:42.125: E/AndroidRuntime(4647): at fortyonepost.com.pwop.TakePictureDemoActivity.onCreate(TakePictureDemoActivity.java:36)
09-21 09:37:42.125: E/AndroidRuntime(4647): at android.app.Activity.performCreate(Activity.java:5008)
09-21 09:37:42.125: E/AndroidRuntime(4647): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
09-21 09:37:42.125: E/AndroidRuntime(4647): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
Невозможно проверить код для всех устройств, я просто проверяю свой код на 5 устройствах и 2 проблемах с устройствами, поэтому есть стандартный способ для извлечения изображения с камеры без намерения и предварительного просмотра.
Обратите внимание, что я включаю в манифест и устанавливаю минимальную версию sdk на 9
Обновление:
В 4.1 Nexus Galaxy takePicture Failed
из строки номер 1061 в классе Camera.java приведена ссылка , которая дает мне информацию о том, что native_takePicture(msgType); function in Camera.java
бросить, что
Ответы
Ответ 1
После нескольких поисков я обнаружил, что предварительный просмотр камеры необходим, и мне интересно, как мой код хорошо работает на некоторых устройствах, даже если он неисправен.
Любые способы решения таковы, что
Мы нуждаемся в предварительном просмотре камеры на поверхности, и мы можем скрыть этот вид поверхности за любым другим видом, я беру поверхностный вид в framelayout (я знаю, что он устарел), и над ним я беру изображение, для поверхностного обзора я просто беру 80 * 80 dp, потому что малый вид поверхности, такой как 30 * 30 дп, не работал и снова через ошибку.
Ответ 2
Работа с камерами в устройствах Android является основной PITA - разные устройства (и даже версии для Android на одном устройстве) могут и, безусловно, будут вести себя по-разному. В основном вы говорите с каким-то демоном на устройстве, и они отличаются друг от друга.
У меня нет решения для всех проблем, но вот мои выводы до сих пор
- не все разрешения работают нормально, даже если они рекламируются в параметрах камеры. Вы должны проверить их при настройке камеры в случае возникновения проблем.
- данные предварительного просмотра приходят к вам через область mmapped памяти
- Формат NV21 всегда предоставляется по умолчанию, но я бы запросил настройки камеры. Когда вы открываете камеру, она может иметь некоторые настройки из другого приложения, которое раньше использовало камеру. (нигде не говорится, что камера будет reset по умолчанию при ее открытии).
Я разработал некоторые элементы управления камерой, разработанные для JavaOCR Project, и это работает на большинстве устройств. Не стесняйтесь использовать это как вдохновение:
http://sourceforge.net/p/javaocr/code/240/tree/trunk/demos/camera-utils/src/main/java/net/sf/javaocr/demos/android/utils/camera/CameraManager.java
Ответ 3
Вам необходимо использовать метод Camera.setOneShotPreviewCallback, а затем обработать изображение
Попробуйте использовать YuvImage и скомпилируйте его перед передачей его в bitmapfactory, например:
YuvImage yuvimage = new YuvImage(byteArr, ImageFormat.NV21, width, height, null);
Rect rect = new Rect(0, 0, width, height);
ByteArrayOutputStream outstr = new ByteArrayOutputStream();
yuvimage.compressToJpeg(rect, 100, outstr);
Bitmap bm = BitmapFactory.decodeByteArray(outstr.toByteArray(), 0, outstr.size());
EDIT:
Вы должны использовать поверхностный вид, но вид поверхности можно скрыть под другим видом, чтобы он не был виден на экране, но все еще существует и активен.