Android Camera 照相机屏幕旋转问题

大多数的相机程序都使用横向拍照,这也是摄像头传感器的自然方向。但是这并不影响您在竖屏的时候拍照,设备的方向信息会存储到图片的EXIF信息中。可以通过函数 setCameraDisplayOrientation() 来改变预览的显示方向而不影响图片的保存数据。然而,在API level 14之前的版本中,在修改预览方向之前需要先停止预览窗口然后重新启动预览。
(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,跟照片尺寸比例不一样,所以预览图像会被拉伸。
<SurfaceView
android:id="@+id/preview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:keepScreenOn="true"
>
</SurfaceView>
解决:在程序中使SurfaceView尺寸比例与照片尺寸比例相同,如下面代码所示;
@Override
public 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();  
        }
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值