(1)旋转手机时,SurfaceView 预览图像反转或旋转90度。 解决:在拍照过程中应该设置为将内容始终横屏显示,这样,在拍照程序中SurfaceView的内容就不会旋转90度或180度了。 在AndroidManifest.xml中设置android:screenOrientation="landscape"。代码如下: <application android:icon="@drawable/icon" android:label="@string/app_name"android:theme="@android:style/Theme.NoTitleBar"><activity android:name=".MainActivity" android:label="@string/app_name"android:screenOrientation="landscape"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter></activity></application>
有些游戏只能横屏玩或只能竖屏玩,所以经常要设置android:screenOrientation,landscape为横屏,portrait为竖屏。
(2)预览图像被拉伸变形 这是由照片图像 跟 预览图像的尺寸比例不一样造成的,例如我的手机是HTC Incredible S 有800万像素,默认的照片尺寸3264*2448(4:3),而我们SurfaceView通常是设为wrap_content如下面mail.xml中的代码所示,拍照时屏幕尺寸大概为800*442(带通知栏)或800*480(全屏),比例约为5:3,跟照片尺寸比例不一样,所以预览图像会被拉伸。 <SurfaceViewandroid:id="@+id/preview"android:layout_width="wrap_content"android:layout_height="wrap_content"android:keepScreenOn="true"></SurfaceView> 解决:在程序中使SurfaceView尺寸比例与照片尺寸比例相同,如下面代码所示; @Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {Camera.Parameters parameters = camera.getParameters();// 获得相机参数Size s = parameters.getPictureSize();double w = s.width;double h = s.height;
if( width>height ){surfaceView.setLayoutParams(new LinearLayout.LayoutParams( (int)(height*(w/h)), height) );}else{surfaceView.setLayoutParams(new LinearLayout.LayoutParams( width, (int)(width*(h/w)) ) );}parameters.setPreviewSize(width, height); // 设置预览图像大小parameters.setPictureFormat(PixelFormat.JPEG); // 设置照片格式camera.setParameters(parameters);// 设置相机参数camera.startPreview();// 开始预览}
(3)拍照图片旋转问题: 解决方法一:要在拍照前,设置rotationn属性,parameters.setRotation()。 在android API Level 14开始出现了android.hardware.Camera.CameraInfo类,可以比较方便地设置摄像机保存图像的旋转角度。
public static void setCameraDisplayOrientation(Activity activity,
int cameraId, android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = activity.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;
}
camera.setDisplayOrientation(result);
}
解决方法二:在oncreate方法中添加OrientationEventListener,OrientationEventListener(方向事件监听器)是一个当方向发生变化时, 从 SensorManager(传感器管理程序)接收通知的辅助类,我就是通过这个来判断手机屏幕的旋转角度,从而将获取后的图片做相应的旋转。
mOrientationListener = new OrientationEventListener(this){ @Override public void onOrientationChanged(int orientation) { orientations =orientation; Log.v("time", "现在是横屏"+orientation); } }; 在onResume中启动事件的监听器
if(mOrientationListener!=null){//先判断下防止出现空指针异常 mOrientationListener.enable(); } 在onPictureTaken中将图片旋转相应的角度:
BitmapFactory.Options opts = new BitmapFactory.Options(); opts.inPreferredConfig = Config.RGB_565; opts.inSampleSize =4; Bitmap bmp = BitmapFactory.decodeByteArray(images, 0, images.length,opts); Matrix matrixs = new Matrix(); if(orientations > 325 || orientations <= 45){ Log.v("time", "Surface.ROTATION_0;"+orientations); matrixs.setRotate(90); }else if(orientations > 45 && orientations <= 135){ Log.v("time", " Surface.ROTATION_270"+orientations); matrixs.setRotate(180); }else if(orientations > 135 && orientations < 225){ Log.v("time", "Surface.ROTATION_180;"+orientations); matrixs.setRotate(270); }else { Log.v("time", "Surface.ROTATION_90"+orientations); matrixs.setRotate(0); } bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrixs, true); 这样图片就旋转过来了,最后别忘了在onPause中将事件监听器关掉:if(mOrientationListener!=null){ mOrientationListener.disable(); }