分享

解决三星调用系统相机拍照显示图片旋转90度横着的问题

 学习的仓库 2017-03-30

最近项目有个功能是调用系统相机拍照上传图片的功能,发现别的手机都没有ok,只有三星的显示图片很明显是旋转了90度,横着的。后来百度了解是三星对Android相机单独做了优化(android碎片化,各种UI。。。你懂得)。所以要想根据路径显示图片时顺带读取图片的信息就行,ExifInterface(exif exchangeable image file) ,这个接口提供了图片文件的旋转,gps,时间等信息(具体的功能可以自行百度)。上代码:

  1. // 从指定路径下读取图片,并获取其EXIF信息  
  2. ExifInterface exifInterface = new ExifInterface(path);  
  3. // 获取图片的旋转信息  
  4. int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,  
  5.         ExifInterface.ORIENTATION_NORMAL);  
  6. Log.e("jxf", "orientation" + orientation);  
  7. switch (orientation) {  
  8. case ExifInterface.ORIENTATION_ROTATE_90:  
  9.     degree = 90;  
  10.     break;  
  11. case ExifInterface.ORIENTATION_ROTATE_180:  
  12.     degree = 180;  
  13.     break;  
  14. case ExifInterface.ORIENTATION_ROTATE_270:  
  15.     degree = 270;  
  16.     break;  

所以我们根据图片的旋转角度信息在onActivityResult方法中将图片旋转过来就行了,这时我们就要用到Matrix这个类生产旋转矩阵:

  1. // 得到图片的旋转角度  
  2. int degree = getBitmapDegree(strImgPath);  
  3. // 根据旋转角度,生成旋转矩阵  
  4. Matrix matrix = new Matrix();  
  5. matrix.postRotate(degree);   
  6. Bitmap returnBm = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);  

而我们想要的正确的图片就在这个returnBm对象中,我们只需imageView.setImageBitmap(returnBm);即可。

上面是我们实现适配三星的核心代码,下面将具体的相机util类奉上,由于我们项目中需要上传图片和图片名字, 所以会在调用相机拍照的同时返回图片名字,具体可以根据自己项目的具体需要自行调整:

  1. /** 
  2.  * 调用系统相机拍照工具类 
  3.  * @author yao 
  4.  * 
  5.  */  
  6. public class CaremaUtil {  
  7.     private static String strImgPath = "";// 照片的绝对路径  
  8.     private static String imgPath = "";// 照片所在文件夹路径  
  9.     // 保存的拍照文件  
  10.     private static File out;  
  11.     /** 
  12.      * 相机照相并返回图片名字 
  13.      */  
  14.     public static String cameraMethod(Activity activity, int requestCode) {  
  15.         // 实例化拍照的Intent  
  16.         Intent imageCaptureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);  
  17.         // 设置图片存放的路径,Environment.getExternalStorageDirectory()得到SD卡的根目录  
  18.         // 先验证手机是否有sdcard  
  19.         String status = Environment.getExternalStorageState();  
  20.         if ((Environment.MEDIA_MOUNTED).equals(status)) {  
  21.             strImgPath = getImgPath();  
  22.             // 本地保存原图  
  23.             File file = new File(strImgPath);  
  24.             Uri u = Uri.fromFile(file);  
  25.             imageCaptureIntent.putExtra(MediaStore.EXTRA_OUTPUT, u);  
  26.             // 启动ACITIVITY  
  27.             activity.startActivityForResult(imageCaptureIntent, requestCode);  
  28.             LogUtil.log("imageName---" + getImageName());  
  29.         } else {  
  30.             Toast.makeText(activity, "没有储存卡", 0).show();  
  31.         }  
  32.         return getImageName();  
  33.     }  
  34.     /** 
  35.      * 返回图片的绝对路径 
  36.      *  
  37.      * @return 
  38.      */  
  39.     public static String getImgPath() {  
  40.         imgPath = getImagePath();// 存放照片的文件夹  
  41.         LogUtil.log("图片存放的路径-----" + strImgPath);  
  42.         String imageName = getImageName();  
  43.         LogUtil.log("图片全名路径---" + imageName);  
  44.         // 检查存放的路径是否存在,如果不存在则创建目录  
  45.         try {  
  46.             out = new File(imgPath);  
  47.             if (!out.exists()) {  
  48.                 out.mkdirs();  
  49.             }  
  50.             // 在此目录下创建文件  
  51.             out = new File(imgPath, imageName);  
  52.         } catch (Exception e) {  
  53.             // TODO Auto-generated catch block  
  54.             e.printStackTrace();  
  55.         }  
  56.         // 该照片的绝对路径  
  57.         strImgPath = imgPath + imageName;  
  58.         return strImgPath;  
  59.     }  
  60.     /** 
  61.      * 得到图片所在的文件夹的路径 
  62.      *  
  63.      * @return 
  64.      */  
  65.     public static String getImagePath() {  
  66.         return Environment.getExternalStorageDirectory().getAbsolutePath() + "//"  
  67.                 + SoftApplication.softApplication.getString(R.string.app_name) + "/approvalPic/";  
  68.     }  
  69.     /** 
  70.      * 得到图片的名字 
  71.      *  
  72.      * @return 
  73.      */  
  74.     public static String getImageName() {  
  75.         // 给相片命名  
  76.         String imageName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".jpg";// 照片命名  
  77.         return imageName;  
  78.     }  
  79.     /** 
  80.      * 显示图片并得到图片字节字符串 
  81.      *  
  82.      * @param resultCode 
  83.      * @param data 
  84.      */  
  85.     public static String showPic(Activity activity, Intent data, ImageView imageView) {  
  86.         String iamgeStr = new String();  
  87.         File file = new File(strImgPath);  
  88.         try {  
  89.             Uri uri = Uri.fromFile(file);  
  90.             BitmapFactory.Options options = new BitmapFactory.Options();  
  91.             options.inJustDecodeBounds = true;  
  92.             // 简单的压缩  
  93.             BitmapFactory.decodeStream(activity.getContentResolver().openInputStream(uri), null, options);  
  94.             options.inSampleSize = 4;  
  95.             options.inJustDecodeBounds = false; // 压缩完后便可以将inJustDecodeBounds设置为false  
  96.             // 把流转化为Bitmap图片  
  97.             Bitmap bitmap = BitmapFactory.decodeStream(activity.getContentResolver().openInputStream(uri), null,  
  98.                     options);  
  99.             android.provider.MediaStore.Images.Media.insertImage(activity.getContentResolver(), bitmap, null, null);  
  100.             activity.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));  
  101.               
  102.             // 得到图片的旋转角度  
  103.             int degree = getBitmapDegree(strImgPath);  
  104.             // 根据旋转角度,生成旋转矩阵  
  105.             Matrix matrix = new Matrix();  
  106.             matrix.postRotate(degree);   
  107.             Bitmap returnBm = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);   
  108.             imageView.setImageBitmap(returnBm);  
  109.             ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  110.             bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);  
  111.             byte[] bitmapByte = baos.toByteArray();  
  112.             iamgeStr = StringUtil.encodeStr(bitmapByte);  
  113.             LogUtil.log("iamgeStr", Log.ERROR, iamgeStr);  
  114.             // LogUtil.log("iamgeStr1", Log.ERROR, imageStr1);  
  115.         } catch (FileNotFoundException e) {  
  116.             e.printStackTrace();  
  117.         } catch (IOException e) {  
  118.             e.printStackTrace();  
  119.         }  
  120.         return iamgeStr;  
  121.     }  
  122.     /** 
  123.      * 清除本地拍照缓存 
  124.      */  
  125.     public static void clearCacheImage() {  
  126.         File filecache = new File(getImagePath());  
  127.         LogUtil.log("filecache---" + filecache.getPath());  
  128.         if (filecache != null && filecache.listFiles() != null) {  
  129.             for (File file : filecache.listFiles()) {  
  130.                 if (file.isFile()) {  
  131.                     file.delete(); // 删除所有文件  
  132.                     LogUtil.log("删除所有文件");  
  133.                 }  
  134.             }  
  135.         }  
  136.     }  
  137.       
  138.     /** 
  139.      * 获取原始图片的角度(解决三星手机拍照后图片是横着的问题) 
  140.      * @param path 图片的绝对路径 
  141.      * @return 原始图片的角度 
  142.      */  
  143.     public static int getBitmapDegree(String path) {  
  144.         int degree = 0;  
  145.         try {  
  146.             // 从指定路径下读取图片,并获取其EXIF信息  
  147.             ExifInterface exifInterface = new ExifInterface(path);  
  148.             // 获取图片的旋转信息  
  149.             int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,  
  150.                     ExifInterface.ORIENTATION_NORMAL);  
  151.             Log.e("jxf", "orientation" + orientation);  
  152.             switch (orientation) {  
  153.             case ExifInterface.ORIENTATION_ROTATE_90:  
  154.                 degree = 90;  
  155.                 break;  
  156.             case ExifInterface.ORIENTATION_ROTATE_180:  
  157.                 degree = 180;  
  158.                 break;  
  159.             case ExifInterface.ORIENTATION_ROTATE_270:  
  160.                 degree = 270;  
  161.                 break;  
  162.             }  
  163.         } catch (IOException e) {  
  164.             e.printStackTrace();  
  165.         }  
  166.         return degree;  
  167.     }  
  168. }  

附上点击调用相机拍照的代码:
  1. public void onClickEvent(View view) {  
  2.     switch (view.getId()) {  
  3.     case R.id.ll_customPic:// 客户合照  
  4.           
  5.         imageName1 = CaremaUtil.cameraMethod(mContext, RESULT_CAPTURE_IMAGE_1);  
  6.         LogUtil.log("imageName1---" + imageName1);  
  7.         break;  
  8.     case R.id.ll_bar_scene:// 柜台场景  
  9.           
  10.         imageName2 = CaremaUtil.cameraMethod(mContext, RESULT_CAPTURE_IMAGE_2);  
  11.         LogUtil.log("imageName2---" + imageName2);  
  12.         break;  
  13.     case R.id.btn_submit:// 提交  
  14.         submitWork();  
  15.         break;  
  16.   
  17.     default:  
  18.         break;  
  19.     }  
  20.   
  21. }  

这里面imageName1,imageName2是要上传的图片名字。
  1.   

另外再附上onActivityResult中的代码:

  1. @Override  
  2. protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
  3.     super.onActivityResult(requestCode, resultCode, data);  
  4.     switch (requestCode) {  
  5.     case RESULT_CAPTURE_IMAGE_1:// 客户合照  
  6.         // 如果返回为正确的的结果  
  7.         if (resultCode == RESULT_OK) {  
  8.             imageStr1 = CaremaUtil.showPic(mContext, data, customPic);  
  9.         }  
  10.         break;  
  11.     case RESULT_CAPTURE_IMAGE_2:// 柜台照片  
  12.         // 如果返回为正确的的结果  
  13.         if (resultCode == RESULT_OK) {  
  14.             imageStr2 = CaremaUtil.showPic(mContext, data, barScene);  
  15.         }  
  16.         break;  
  17.     }  
  18. }  

这里面imageStr1,imageStr2是要上传图片的二进制流的字符串。


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多