某些设备中的 Surface 设置参数错误

Error in Surface set parameters in some device

我在我的应用程序中实现了 Surface,它可以在某些设备(galaxy、htc 等)上 运行 但在索尼 Xperia 中,当我的 activity 加载时,我在设置参数时出现错误, 我该如何解决这个错误?

Activity :

public class TakePhotoActivity extends Activity  implements SurfaceHolder.Callback, Camera.ShutterCallback, Camera.PictureCallback{



Camera mCamera;
SurfaceView mPreview;

boolean isPreviewRunning;




protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_photo_capture);

    mPreview = (SurfaceView)findViewById(R.id.preview);
    mPreview.getHolder().addCallback(this);
    mPreview.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

  mCamera = Camera.open();

}



@Override
public void onPause() {

        super.onPause();
        mCamera.stopPreview();
        finish();

}

@Override
public void onDestroy() {
    super.onDestroy();
    mCamera.release();

}

public void onCancelClick(View v) {
    finish();
}

public void onSnapClick(View v) {
    mCamera.takePicture(this, null, null, this);
 }

public void onSaveClick(View v) {

}

@Override
public void onShutter() {
    //Toast.makeText(this, "Click!", Toast.LENGTH_SHORT).show();
}



@Override
public void onPictureTaken(byte[] data, Camera camera) {

    try {

       /*try {
            File file = new File(Environment.getExternalStorageDirectory().getPath() + File.separator +"DocumentsWallet" );
            if( ! file.exists()){
                file.mkdirs();
            }

            FileOutputStream out = new FileOutputStream(file.getPath()+"/pic.jpeg");
            out.write(data);
            out.flush();
            out.close();
        }catch(Exception ex){
            Toast.makeText(this,ex.getMessage(),Toast.LENGTH_LONG).show();
        }*/


        Photos img=new Photos();

        Bitmap bmp=img.convertArrayByteToBitmap(data);
        Bitmap bitmap=img.rotateImage(bmp,90);
        showPhoto(bitmap);


    } catch (Exception e) {
        Toast.makeText(this,"Error in onPictureTaken method : "+e.getMessage(),Toast.LENGTH_LONG).show();

    }

    camera.startPreview();

}





private void showPhoto(Bitmap bitmap) {

    ImageView img = (ImageView) findViewById(R.id.imageView2);

    mPreview.setVisibility(View.INVISIBLE);
    img.setImageBitmap(bitmap);
    img.setVisibility(View.VISIBLE);
 }


@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {


    try {

        if (isPreviewRunning) {
            mCamera.stopPreview();
        }


        Camera.Parameters params = mCamera.getParameters();
        Camera.Size selected = getBestPreviewSize();
        params.setPreviewSize(selected.width, selected.height);
        params.setPictureSize(selected.width, selected.height);

        setCameraDisplayOrientation();
        params.setPictureFormat(PixelFormat.JPEG);
        mCamera.setParameters(params);
        isPreviewRunning = true;
        mCamera.startPreview();
    }catch (Exception ex){

    }

}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    try {
        mCamera.setPreviewDisplay(mPreview.getHolder());

    } catch (Exception e) {
        Toast.makeText(this,e.getMessage(),Toast.LENGTH_SHORT).show();
    }
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {

    isPreviewRunning = false;
}





private Camera.Size getBestPreviewSize( ) {



    List<Camera.Size> sizeList = mCamera.getParameters().getSupportedPreviewSizes();
    Toast.makeText(this,sizeList.size()+"",Toast.LENGTH_LONG).show();
    Camera.Size bestSize = sizeList.get(0);
    for(int i = 1; i < sizeList.size(); i++){

        if( (sizeList.get(i).width * sizeList.get(i).height) > ( bestSize.width * bestSize.height  ) ){
            bestSize = sizeList.get(i);
         }
    }

    return bestSize;
}




private void setCameraDisplayOrientation(){

    try {

        android.hardware.Camera.CameraInfo info =
                new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, info);
        int rotation = getWindowManager().getDefaultDisplay()
                .getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }

        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360;  // compensate the mirror
        } else {  // back-facing
            result = (info.orientation - degrees + 360) % 360;
        }
        mCamera.setDisplayOrientation(result);

    }catch (Exception ex){
        Toast.makeText(this,"Error in setCameraDisplayOrientation() method :  "+ex.getMessage(),Toast.LENGTH_LONG).show();
    }
  }

}

当我删除并 params.setPictureSize(selected.width, selected.height); 错误解决时,但我需要最适合我的图片的尺寸。任何人都可以帮助我吗?

您在图片尺寸中添加了与预览尺寸相同的高度和宽度。我不确定索尼 Xperia 的情况,但某些设备的预览尺寸和图片尺寸比例可能不同。 所以最好的选择是获得所选尺寸的宽高比(你从 getBestPreviewSize() 获得)并从 List<Size> imageSizes = mCamera.getParameters().getSupportedPictureSizes(); 中找到相同宽高比的图片尺寸的最佳匹配。您可以查看详细答案here