我正在开发API 7(2.1)。我实现了这样的相机视图:
public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
SurfaceHolder mHolder;
int width;
int height;
Camera mCamera;
public CameraView(Context context, AttributeSet attrs) {
super(context, attrs);
initHolder();
}
public CameraView(Context context) {
super(context);
initHolder();
}
private void initHolder() {
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, acquire the camera and tell it where to
// draw.
mCamera = Camera.open();
// Parameters params = mCamera.getParameters();
// // If we aren't landscape (the default), tell the camera we want
// // portrait mode
// if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
// params.set("orientation", "portrait"); // "landscape"
// // And Rotate the final picture if possible
// // This works on 2.0 and higher only
// // params.setRotation(90);
// // Use reflection to see if it exists and to call it so you can
// // support older versions
// try {
// Method rotateSet = Camera.Parameters.class.getMethod("setRotation", new Class[] { Integer.TYPE });
// Object arguments[] = new Object[] { new Integer(90) };
// rotateSet.invoke(params, arguments);
// } catch (NoSuchMethodException nsme) {
// // Older Device
// Log.v("CAMERAVIEW", "No Set Rotation");
// } catch (IllegalArgumentException e) {
// Log.v("CAMERAVIEW", "Exception IllegalArgument");
// } catch (IllegalAccessException e) {
// Log.v("CAMERAVIEW", "Illegal Access Exception");
// } catch (InvocationTargetException e) {
// Log.v("CAMERAVIEW", "Invocation Target Exception");
// }
// }
// mCamera.setParameters(params);
setDisplayOrientation(mCamera, 90);
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
mCamera.release();
mCamera = null;
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
// Because the CameraDevice object is not a shared resource, it's very
// important to release it when the activity is paused.
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
width = w;
height = h;
// Now that the size is known, set up the camera parameters and begin the preview.
Camera.Parameters parameters = mCamera.getParameters();
//parameters.setPreviewSize(w, h);
mCamera.setParameters(parameters);
mCamera.startPreview();
}
public void takePicture(Camera.ShutterCallback shutter, Camera.PictureCallback raw, Camera.PictureCallback jpeg) {
mCamera.takePicture(shutter, raw, jpeg);
}
protected void setDisplayOrientation(Camera camera, int angle){
Method downPolymorphic;
try {
downPolymorphic = camera.getClass().getMethod("setDisplayOrientation", new Class[] { int.class });
if (downPolymorphic != null) {
downPolymorphic.invoke(camera, new Object[] { angle });
}
} catch (Exception e1) {}
}
}
只有使用反射的方法(取自Williew在Android camera rotate中的答案)才能在我的设备上以正确的旋转显示预览,否则,预览总是旋转-90°
到目前为止一直很好,但现在我还有另外一个问题。当我使用activitie的回调获取位图时:
public void onPictureTaken(byte[] data, Camera camera) {
Bitmap b = BitmapFactory.decodeByteArray(data, 0, data.length);
Log.d("test", "---width: " + b.getWidth() + " height: " + b.getHeight());
}
它始终处于横向模式! (在这种情况下2560 x 1920)。因此,如果用户在纵向模式下拍摄设备的照片,我得到一个位图2560 x 1920,无论如何,无论如何,当我放入图像视图时,由于某种原因看起来与我拍摄的肖像照片完全相同。问题出现在用户拍摄设备处于横向模式的照片时,我想旋转它,以便以纵向模式显示结果(按比例缩小) - 或者为风景照片做一些其他特殊操作。
但是我无法将它们与肖像照片区分开来,因为位图的尺寸是相同的:/
如何识别肖像/风景图片?
任何想法......?我是相机的新手,有点失落...... 提前谢谢。
修改 好吧,我认为没有问题,尺寸总是一样的,因为无论我如何握住设备,图片实际上总是具有相同的尺寸。只有我不明白的是为什么我总是得到宽度>预览和图片明显处于纵向模式时的高度。