由于项目的需要,没有自定义拍照功能,仅仅调用了系统的拍照程序..但是出现了一个问题,就是拍照完成显示图片居然是被旋转的图片....
需求:做仿新浪发微博的项目,能够上传图片还有两外一个项目用到手机拍摄图片,这两个都需要把图片上传到服务器
遇到问题:有的手机拍摄的图片旋转90度,有的图片旋转了180度,有的手机是正常的,服务器要求的是正的,这样问题就来了,不能用户发个照片在微博上看到的是被旋转了的啊,另外一个项目里旋转了的图片直接匹配出现问题,这个更严重。
解决:开始的时候在网上没有找到很好的解决办法,谷歌百度的搜了一通,想到第一种解决方式,当手机拍照结束,在返回结果处理里面立即跳转到一个新的页面,在新的页面里让用户自己手动去旋转图片,然后点击确定。就可以上传到服务器正着的图片了;第二种解决方式,这是在论坛里发现的一个方法,可以获取图片的属性,读取图片的旋转角度。
第一种方式代码:
在onActivityResult里面处理跳转
- <span style="font-size:18px;"> Intent intent = new Intent(SendMicoBlog.this, RotaingActivity.class);
- MyApp myApp = (MyApp)getApplication();
- myApp.setName(bitmap);
- myApp.setPhoto(isPhoto);
- startActivityForResult(intent, 1);</span>
在RotaingActivity里面就可以作相应的旋转处理了
- <span style="font-size:18px;">
- MyApp myApp = (MyApp)getApplication();
- bitmap = myApp.getName();
- System.out.println("RotaingActivity w = " + bitmap.getWidth() + "H = " + bitmap.getHeight());
- myBitmap = bitmap;
- myWidth = bitmap.getWidth();
- myHeight = bitmap.getHeight();
-
-
- matrix = new Matrix();
- Drawable drawable = ImageDispose.bitmapToDrawable(bitmap);
- imageView.setBackgroundDrawable(drawable);
-
-
- btnCancel.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
-
- RotaingActivity.this.finish();
- }
- });
-
- btnRightRotaing.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- myBitmap = rotaingImageView(-90);
- }
- });
-
- btnLeftRotaing.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- myBitmap = rotaingImageView(+90);
- }
- });
-
- btnOK.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- MyApp myApp = (MyApp)getApplication();
- myApp.setName(myBitmap);
- System.out.println("OK resultcoder");
- Intent intent = new Intent(RotaingActivity.this, SendMicoBlog.class);
- setResult(6, intent);
- RotaingActivity.this.finish();
- }
- });
- }
- private Bitmap rotaingImageView(int angle2) {
-
- matrix.postRotate(angle2);
- System.out.println("angle2=" + angle2);
-
- Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
- myWidth, myHeight, matrix, true);
- Drawable drawable = ImageDispose.bitmapToDrawable(resizedBitmap);
- imageView.setBackgroundDrawable(drawable);
- return resizedBitmap;
- }</span>
第二种方式:就简单多了,直接自己出偷着把照片给处理了,不需要用户的操作,这样体验会更好一点。
在onActivityResult里面处理
- BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
- bitmapOptions.inSampleSize = 8;
- File file = new File(SD_CARD_TEMP_DIR);
-
-
-
- int degree = ImageDispose.readPictureDegree(file.getAbsolutePath());
- <span style="font-size:18px;">Bitmap cameraBitmap = BitmapFactory.decodeFile(SD_CARD_TEMP_DIR, bitmapOptions);
- bitmap = cameraBitmap;
-
-
-
- bitmap = ImageDispose.rotaingImageView(degree, bitmap);
- upload(bitmap);</span>
- <span style="font-size:18px;">
-
-
-
-
-
- public static Bitmap rotaingImageView(int angle , Bitmap bitmap) {
-
- Matrix matrix = new Matrix();;
- matrix.postRotate(angle);
- System.out.println("angle2=" + angle);
-
- Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
- bitmap.getWidth(), bitmap.getHeight(), matrix, true);
- return resizedBitmap;
- }</span>
-
-
-
-
-
- public static int readPictureDegree(String path) {
- int degree = 0;
- try {
- ExifInterface exifInterface = new ExifInterface(path);
- int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
- switch (orientation) {
- case ExifInterface.ORIENTATION_ROTATE_90:
- degree = 90;
- break;
- case ExifInterface.ORIENTATION_ROTATE_180:
- degree = 180;
- break;
- case ExifInterface.ORIENTATION_ROTATE_270:
- degree = 270;
- break;
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- return degree;
- }
这样就搞定了,此时你上传的照片就是正的了。
第一种方式的图片
http://asysbang.com/forum.php?mod=viewthread&tid=58&extra=page%3D1
1、预览时正确显示
主要参考系统相机代码实现getDisplayOritation就可以了
//在preview之前调用setDisplayOrientation
int degrees = getDisplayOritation(getDispalyRotation(), cameraId);
mCamera.setDisplayOrientation(degrees);
mCamera.startPreview();
getDisplayOritation函数如下:
private int getDisplayOritation(int degrees, int cameraId) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(cameraId, info);
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360;
} else {
result = (info.orientation - degrees + 360) % 360;
}
return result;
}
private int getDispalyRotation() {
int i = getWindowManager().getDefaultDisplay().getRotation();
switch (i) {
case Surface.ROTATION_0:
return 0;
case Surface.ROTATION_90:
return 90;
case Surface.ROTATION_180:
return 180;
case Surface.ROTATION_270:
return 270;
}
return 0;
}
2、显示图片时正确显示
竖屏拍照的照片,直接使用的话,会旋转90度
参考系统图库的代码,需要先查询mediascanner的orientation字段,然后应用再把角度旋转过来,这样显示就ok了
参考代码如下:
假设c为查询mediaprovider数据库返回的cursor
int rotation = c.getInt(c.getColumnIndex(MediaStore.Images.ImageColumns.ORIENTATION));
if (rotation != 0) {
Bitmap bitmap = BitmapFactory.decodeFile(path);
imageBefore.setImageBitmap(bitmap);
Matrix m = new Matrix();
m.setRotate(rotation);
Bitmap transformed = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
return transformed;
}