Capture image without intent, Gives different output on different devices

My requirement is neither to display camera preview nor to use camera intent for image capture.

There for I find a way which is working for my first testing device (Galaxy tab 7").

My CaptureImage function is as below

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

and getCameraID function as below

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

Now I am facing difficulty to run successfully above code on different devices.

  • Samsung Galaxy S+ (2.3.6) : Front camera always return green image but coding for Back camera working fine.
  • Samsung Galaxy Nexus (4.1) : coding doesn't work Neither for Front nor for Back camera & gives "takePicture" failed.
  • LG Optimus Net (2.3.4) : only back camera is there & working fine.
  • Samsung Galaxy Tab 7 " (2.3.3) : both camera working fine.
  • Motorola Xoom (3.1) : both camera working fine.
  • Logcat of 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)
    

    It is not possible to check code for every devices , I just test my code on 5 devices and 2 device causes problem, so is there any standard way to fetch image from camera without intent & preview.

    Please note that I include in manifest & set minimum sdk version to 9

    Update : In 4.1 Nexus Galaxy takePicture Failed from Line number 1061 in Camera.java class, here is the class link which gives me information that native_takePicture(msgType); function in Camera.java native_takePicture(msgType); function in Camera.java did throw that


    Camera handling in android devices is major PITA - different devices ( and even android versions on same device) can and certainly will behave differently. Basically you are speaking with some demon process on device, and they are different from each other.

    I do not have solution for all problems, but here are my findings so far

  • not all resolutions are working properly, even it they are advertised in camera parameters. You have to test them while setting up camera in case there are problems
  • preview data come to you via mmapped memory region
  • NV21 format is always supplied and shall be default, but I would query camera settings. When you open camera, it can have some settings from other application which used camera just before. ( it is said nowhere that camera will be reset to defaults when you open it )
  • I have developed some camera management stuff developed for JavaOCR Project, and it kind of works on most devices. Feel free to use this as inspiration:

    http://sourceforge.net/p/javaocr/code/240/tree/trunk/demos/camera-utils/src/main/java/net/sf/javaocr/demos/android/utils/camera/CameraManager.java


    After several search, i found that preview of camera is necessary and i wonder how my code works well in some devices even it is faulty.

    Any ways solution is that,

    We require camera preview hold on surface view and we can hide that surface view behind any other view, I take surface view in framelayout(i know it is deprecated) and above it i take image view, for surface view i just take 80*80 dp surface view because small surface view like 30*30 dp didn't work and again through error.


    You need to use the Camera.setOneShotPreviewCallback method and then process the image

    Try using YuvImage and compress it before passing it to the bitmapfactory, like so:

    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:

    You must use a surface view but the surface view can be hidden below another view so it's not visible on screen but still exists and active.

    链接地址: http://www.djcxy.com/p/90934.html

    上一篇: 如何禁用android版本4.3 rooted设备中的飞行模式?

    下一篇: 无意捕获图像,在不同设备上提供不同的输出