简体   繁体   中英

Android Samsung Galaxy S4 Custom Camera Preview Distorted

I am using custom camera in my app built with target sdk 22. I have tested camera through my app on many devices including Samsung S5, Samsung Note 4 and huawei ascend mate 7 and Image preview is fine.

But when I open Camera through my app in Samsung Galaxy S4 (Android 5.0.1) I get camera preview distorted. Following is the image of the preview:

在此处输入图片说明

I have seen many posts on stackoverflow but they about after capturing the image and my problem is before capturing the picture.

Following is the code I am using for the preview:

  1. surfaceChanged Method

      public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { try { holder.addCallback(this); holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); Camera.Parameters parameters = camera.getParameters(); try { List<Camera.Size> supportedSizes = null; supportedSizes = Compatibility.getSupportedPreviewSizes(parameters); //preview form factor float ff = (float)w/h; Log.d("", "Screen res: w:"+ w + " h:" + h + " aspect ratio:" + ff); //holder for the best form factor and size float bff = 0; int bestw = 0; int besth = 0; Iterator<Camera.Size> itr = supportedSizes.iterator(); while(itr.hasNext()) { Camera.Size element = itr.next(); //current form factor float cff = (float)element.width/element.height; Log.d("Camera", "Candidate camera element: w:"+ element.width + " h:" + element.height + " aspect ratio:" + cff); int currentRes = element.width*element.height; //ff = Asp ratio of current Screen // cff = Asp ratio of current Size from Size list // bff = Asp ratio of current best aspect ratio selected if ((Math.abs(ff-cff) <= Math.abs(ff-bff) ) ) { bff=cff; bestw = element.width; besth = element.height; } } Log.d("Camera", "Chosen camera element: w:"+ bestw + " h:" + besth + " aspect ratio:" + bff); if ((bestw == 0) || (besth == 0)){ Log.d("Camera", "Using default camera parameters!"); bestw = 480; besth = 320; Log.d("Camera","Using default camera parameters! aspect ratio "+480/320); } parameters.setPreviewSize(bestw, besth); //Handling camera angle switch(this.getWindowManager().getDefaultDisplay().getRotation()){ case 0: camera.setDisplayOrientation(90); break; case 1: camera.setDisplayOrientation(0); break; case 2: case 3: camera.setDisplayOrientation(180); break; } } catch (Exception ex) { parameters.setPreviewSize(480 , 320); } camera.setParameters(parameters); camera.startPreview(); } catch (Exception ex) { ex.printStackTrace(); } } 
  2. Compatibility.getSupportedPreviewSizes(parameters) Method

      @SuppressWarnings("unchecked") public static List<Camera.Size> getSupportedPreviewSizes(Camera.Parameters params) { List<Camera.Size> retList = null; try { Object retObj = mParameters_getSupportedPreviewSizes.invoke(params); if (retObj != null) { retList = (List<Camera.Size>)retObj; } } catch (InvocationTargetException ite) { /* unpack original exception when possible */ Throwable cause = ite.getCause(); if (cause instanceof RuntimeException) { throw (RuntimeException) cause; } else if (cause instanceof Error) { throw (Error) cause; } else { /* unexpected checked exception; wrap and re-throw */ throw new RuntimeException(ite); } } catch (IllegalAccessException ie) { //System.err.println("unexpected " + ie); } return retList; } 

I would appreciate any kind of help.

Thanks in advance.

On Samsung Note IV, I realised that you just should not use setPreviewSize(), even though the sizes you get from getSupportedPreviewSizes() ought to be legal and usable.

It is an awkward bug in Samsung's low level camera software. Uncool, Samsung! It reproduces only with some devices.

Still shooting, however, is impeccable. So, here is my code:

    Camera.Parameters parameters = camera.getParameters();

    boolean currentPreviewSettingsAreValid = parameters != null;
    currentPreviewSettingsAreValid = currentPreviewSettingsAreValid && parameters.getPreviewSize() != null;
    currentPreviewSettingsAreValid = currentPreviewSettingsAreValid && parameters.getPreviewSize().width > 0 && parameters.getPreviewSize().height > 0;

    if (parameters != null && !currentPreviewSettingsAreValid) {
        Camera.Size bestSize = getBestSizeOfSupported(parameters.getSupportedPreviewSizes(), width, height);

        if (bestSize != null) {
            parameters.setPreviewSize(bestSize.width, bestSize.height);
        }
    }

Hoping it helps anybody

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM