Android 自定义相机实现的怪异预览

Android 自定义相机实现的怪异预览,android,android-camera,photo,Android,Android Camera,Photo,我已经在我的应用程序中实现了自定义照相机活动。相机在我的Nexus5上工作得很好。然而,在阿尔卡特一触式星上,当我停止预览以显示快照时,我得到了这个预览 此外,PictureCallback的字节数组是正确的。事实上,如果我将数组解码成位图,我就能正确地看到它 下面是我的SurfaceView相机预览的实现 public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { private Sur

我已经在我的应用程序中实现了自定义照相机活动。相机在我的Nexus5上工作得很好。然而,在阿尔卡特一触式星上,当我停止预览以显示快照时,我得到了这个预览

此外,
PictureCallback
的字节数组是正确的。事实上,如果我将数组解码成
位图
,我就能正确地看到它

下面是我的
SurfaceView
相机预览的实现

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
private int mPhotoRotation;

public CameraPreview(Context context) {
    super(context);
}

@SuppressLint("InlinedApi")
@SuppressWarnings("deprecation")
public CameraPreview(Context context, Camera camera) {
    super(context);
    mCamera = camera;

    Camera.Parameters parameters = camera.getParameters();
    List<String> focusModes = parameters.getSupportedFocusModes();

    if (focusModes != null && focusModes.contains(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE))
        parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
    else if (focusModes != null && focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO))
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
    if (parameters.getSupportedFlashModes() != null && parameters.getSupportedFlashModes().contains(Parameters.FLASH_MODE_AUTO))
        parameters.setFlashMode(Parameters.FLASH_MODE_AUTO);
    camera.setParameters(parameters);

    mHolder = getHolder();
    mHolder.addCallback(this);

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB)
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    try {
        mCamera.setPreviewDisplay(holder);
        mCamera.startPreview();
    } catch (IOException e) {
    }
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    if (mCamera != null) {
        mCamera.stopPreview();
        Parameters parameters = mCamera.getParameters();
        List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
        Camera.Size size = getOptimalPreviewSize(previewSizes, width, height);

        parameters.setPreviewSize(size.width, size.height);
        mCamera.setParameters(parameters);

        Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
        mPhotoRotation = 0;
        if (display.getRotation() == Surface.ROTATION_0) {
            mPhotoRotation = 90;
        } else if (display.getRotation() == Surface.ROTATION_270) {
            mPhotoRotation = 180;
        }
        mCamera.setDisplayOrientation(mPhotoRotation);
        mCamera.startPreview();
    }
}

private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
    final double ASPECT_TOLERANCE = 0.1;
    double targetRatio = (double) h / w;

    Camera.Size optimalSize = null;
    double minDiff = Double.MAX_VALUE;

    int targetHeight = h;

    for (Camera.Size size : sizes) {
        double ratio = (double) size.width / size.height;
        if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
            continue;
        if (Math.abs(size.height - targetHeight) < minDiff) {
            optimalSize = size;
            minDiff = Math.abs(size.height - targetHeight);
        }
    }

    if (optimalSize == null) {
        minDiff = Double.MAX_VALUE;
        for (Camera.Size size : sizes) {
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
    }
    return optimalSize;
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}

public int getPhotoRotation() {
    return mPhotoRotation;
}

}
回调只保留字节数组的备份并停止预览

mPictureCallback = new PictureCallback() {
        public void onPictureTaken(byte[] data, Camera camera) {
            mPhotoJpeg = data;
            mCamera.stopPreview();
        }
    };

那么,这种行为的原因是什么呢?为什么只在阿尔卡特上而不在nexus 5上?

这看起来似乎是某种程度上的分辨率错误。。。就像你每641像素读取一次而不是640像素。。。也许help@Rajesh不还是一样的问题:(使用这个类,它本身应该可以工作,因为我使用了它,而且我有一个正在运行的应用程序。问题是,我的版本也可以在nexus 5上工作……但在阿尔卡特一键启动上它不能。
mPictureCallback = new PictureCallback() {
        public void onPictureTaken(byte[] data, Camera camera) {
            mPhotoJpeg = data;
            mCamera.stopPreview();
        }
    };