2014-08-27 48 views
1

我一直被困在相机6天,但没有得到任何适当的解决方案。当我通过相机意图拍摄图像时,图像正在旋转。我试图修复方向,但有时它不会在onActivityResult()中提供位图值。当我尝试在ImageView中设置图像时,它会显示黑屏。这里是我的代码请帮助我 -为什么图像在通过相机意图捕获后旋转?

//call intent to capture image 
captureBtn.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View arg0) { 
       // TODO Auto-generated method stub 
       try { 
      Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
      if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) 
      { 
       startActivityForResult(takePictureIntent,AlletConstants.CAPTURE_RECEIPT_IMAGE); 
      } 

     } catch (Exception e) { 

      e.printStackTrace(); 
     } 
      } 
}); 


@Override 
    public void onActivityResult(int requestCode, int resultCode, Intent data) { 
     super.onActivityResult(requestCode, resultCode, data); 

     switch (requestCode) { 
     case AlletConstants.CAPTURE_RECEIPT_IMAGE: 
      if(data != null) 
      { 
       Uri qrcodeImageUri = data.getData(); 
       bitmapReceiptImage = handleQrBarCodeImage(qrcodeImageUri); 
       mImageCaptureUri = AlletCommonUtility.bitmapToUri(getActivity(), bitmapReceiptImage); 
       doCrop(); 
       AlletCommonUtility.showToast(getActivity(),"Uri = "+mImageCaptureUri); 
      } 

      break; 

     case AlletConstants.CROP_RECEIPT_FROM_CAMERA: 
      if(data != null) 
      { 
       Bundle qrcodeextras = data.getExtras(); 
       if (qrcodeextras != null) { 
        Bitmap cropBitmap = qrcodeextras.getParcelable("data"); 
        receiptImageView.setImageBitmap(cropBitmap); 
        bitmapReceiptImage = cropBitmap; 
       } 

       File qrcodeFile = new File(mImageCaptureUri.getPath()); 
       if (qrcodeFile.exists()) 
        qrcodeFile.delete(); 
      } 

      break;  

     default: 
      break; 
     } 

    } 




// use to get bitmap from uri 
    private Bitmap handleReceiptImage(Uri selectedImageUri) 
    {  
     String[] filePathColumn = {MediaStore.Images.Media.DATA }; 

     Cursor cursor = getActivity().getContentResolver().query(selectedImageUri, filePathColumn, null, null, null); 
     cursor.moveToFirst(); 

     int columnIndex = cursor.getColumnIndex(filePathColumn[0]); 
     picturePath = cursor.getString(columnIndex); 
     cursor.close(); 
     Bitmap bitmap = setCameraImageRotation(picturePath); 
     return bitmap; 
    } 

    private Bitmap setCameraImageRotation(String picturePath) 
    { 
     Bitmap bitmapQrBarImage = null; 
     try { 
       File f = new File(picturePath); 
       ExifInterface exif = new ExifInterface(f.getPath()); 
       int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);  
       AlletCommonUtility.showToast(getActivity(), "Orienattion = "+orientation); 
       Matrix mat = new Matrix(); 
       mat.postRotate(getImageOrientation(orientation)); 
       BitmapFactory.Options options = new BitmapFactory.Options(); 
       options.inSampleSize= 4; 
       Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f), null, options); 
       bitmapQrBarImage = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), mat, true);  

       if (bitmapQrBarImage != null) { 
        AlletCommonUtility.showToast(getActivity(), "CAMERA_PIC_SELECTION = "+bitmapQrBarImage); 
       } 
      } 
      catch (IOException e) { 
       Log.w("TAG", "-- Error in setting image"); 
      } 
      catch(OutOfMemoryError oom) { 
       Log.w("TAG", "-- OOM Error in setting image"); 
      } 

     return bitmapQrBarImage; 

    } 



// Use to crop image 
    private void doCrop() { 
     final ArrayList<CropOption> cropOptions = new ArrayList<CropOption>(); 
     Intent intent = new Intent("com.android.camera.action.CROP"); 
     intent.setType("image/*"); 

     List<ResolveInfo> list = getActivity().getPackageManager().queryIntentActivities(intent, 0); 

     int size = list.size(); 

     if (size == 0) {  
      AlletCommonUtility.showToast(getActivity(), AlletMessage.NOT_CROP_IMAGE);   
      return; 
     } else { 
      intent.setData(mImageCaptureUri); 

      intent.putExtra("outputX", 200); 
      intent.putExtra("outputY", 200); 
      intent.putExtra("aspectX", 1); 
      intent.putExtra("aspectY", 1); 
      intent.putExtra("scale", true); 
      intent.putExtra("return-data", true); 

      if (size == 1) { 
       Intent i  = new Intent(intent); 
       ResolveInfo res = list.get(0); 

       i.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name)); 
       startActivityForResult(i, AlletConstants.CROP_RECEIPT_FROM_CAMERA); 

      } else { 
       for (ResolveInfo res : list) { 
        final CropOption co = new CropOption(); 

        co.title = getActivity().getPackageManager().getApplicationLabel(res.activityInfo.applicationInfo); 
        co.icon  = getActivity().getPackageManager().getApplicationIcon(res.activityInfo.applicationInfo); 
        co.appIntent= new Intent(intent); 

        co.appIntent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name)); 

        cropOptions.add(co); 
       } 

       CropOptionAdapter adapter = new CropOptionAdapter(getActivity(), cropOptions); 

       AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 
       builder.setTitle("Choose Crop App"); 
       builder.setAdapter(adapter, new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog, int item) { 
         startActivityForResult(cropOptions.get(item).appIntent, AlletConstants.CROP_RECEIPT_FROM_CAMERA); 
        } 
       }); 

       builder.setOnCancelListener(new DialogInterface.OnCancelListener() { 
        @Override 
        public void onCancel(DialogInterface dialog) { 

         if (mImageCaptureUri != null) { 
          getActivity().getContentResolver().delete(mImageCaptureUri, null, null); 
          mImageCaptureUri = null; 
         } 
        } 
       }); 

       AlertDialog alert = builder.create(); 

       alert.show(); 
      } 
     } 
    } 



// use to rotate captured image from device camera 
public static int getImageOrientation(int rotation) 
    { 
     int angle = 0; 

      switch (rotation) { 
      case 0: 
       angle = 90; 
       break; 

      case ExifInterface.ORIENTATION_ROTATE_90: 
       angle = 90; 
       break; 

      case ExifInterface.ORIENTATION_ROTATE_180: 
       angle = 180; 
       break; 

      case ExifInterface.ORIENTATION_ROTATE_270: 
       angle = 270; 
       break; 
      default: 
       break; 
      } 

      return angle; 

    } 

我得到的图像在横向模式,但不是在potrait模式。拍摄图像后,相机预览会自动旋转90度。

回答

2

这是因为图像的EXIF数据。您需要使用旋转方法。

0

根据您的内置摄像头的方向和设备的方向,图片会有不同的旋转。你通过ExifInterface检查你的特定图像的旋转。

/** 
* @param filename  Path to image file 
* @param captureTime Time when image file was created 
*/ 
public static int extractExifOrientationTagFromImageFile(String filename, long creationTime) { 
    /* The issue is on some devices, there's a bug that makes the picture taken saved in your app folder without proper 
     exif tags while a properly rotated image is saved in the android default folder (even though it shouldn't be). 
     Now what we do is recording the time when we're starting the camera app. Then we query 
     the Media Provider to see if any pictures were saved after this timestamp we've saved. That means most likely Android OS 
     saved the properly rotated picture in the default folder and of course put an entry in the media store and we can use the 
     rotation information from this row. */ 
    int imageRotation = -1; 
    long imageFileSize = new File(filename).length(); 

    Cursor mediaFileCursor = getContext().getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
      new String[] { MediaStore.Images.ImageColumns.ORIENTATION, MediaStore.MediaColumns.SIZE }, 
      MediaStore.MediaColumns.DATE_ADDED + " >= ?", new String[] { String.valueOf(creationTime/1000 - 1) }, 
      MediaStore.MediaColumns.DATE_ADDED + " DESC"); 
    if((mediaFileCursor != null) && (mediaFileCursor.getCount() != 0)) { 
     while(mediaFileCursor.moveToNext()) { 
      long mediaFileSize = getLongFromCursor(mediaFileCursor, MediaStore.MediaColumns.SIZE); 
      // Extra check to make sure that we are getting the orientation from the proper file 
      if(mediaFileSize == imageFileSize) { 
       imageRotation = getIntFromCursor(mediaFileCursor, MediaStore.Images.ImageColumns.ORIENTATION); 
       break; 
      } 
     } 
    } 

    /* Now if the rotation at this point is still -1, then that means this is one of the devices with proper rotation information. */ 
    if(imageRotation == -1) { 
     ExifInterface exif = null; 
     try { 
      exif = new ExifInterface(filename); 
     } 
     catch (IOException e) { 
      e.printStackTrace(); 
     } 
     imageRotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1); 
    } 

    return imageRotation; 
} 

private static final int COLUMN_NOT_EXISTS = -1; 

public static Long getLongFromCursor(Cursor cursor, String columnName) { 
    int columnIndex; 
    if((columnIndex = cursor.getColumnIndex(columnName)) != COLUMN_NOT_EXISTS) { 
     return cursor.getLong(columnIndex); 
    } 
    else { 
     return null; 
    } 
} 

public static Integer getIntFromCursor(Cursor cursor, String columnName) { 
    int columnIndex; 
    if((columnIndex = cursor.getColumnIndex(columnName)) != COLUMN_NOT_EXISTS) { 
     return cursor.getInt(columnIndex); 
    } 
    else { 
     return null; 
    } 
} 

现在,当你有你的图像旋转,你可以旋转它的位图正确:

int imageRotation = extractExifOrientationTagFromImageFile(lastCapturedMediaUriPath, cameraAppInvokeTime); 
Matrix matrix = new Matrix(); 
switch(imageRotation) { 
    case ExifInterface.ORIENTATION_ROTATE_90: 
     matrix.postRotate(90); 
     break; 
    case ExifInterface.ORIENTATION_ROTATE_180: 
     matrix.postRotate(180); 
     break; 
    case ExifInterface.ORIENTATION_ROTATE_270: 
     matrix.postRotate(270); 
     break; 
    default: 
     break; 
} 
final Bitmap loadedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); 
+0

非常感谢您的回答,但可以请你告诉我,我将如何得到CameraInvokeAppTime为extractOrientationTagFromImageFile()。 – 2014-08-28 04:48:07

+0

在通过intent调用Camera app之前,只需调用System.currentTimeMillis()方法并将其返回的值传递给extractOrientationTagFromImageFile()。 – 2014-08-28 14:14:50

+0

嗨,Michal,我的轮换问题仍然没有解决。我正在使用LG设备。当我捕捉Potrait模式下显示的图像和预览时,它不会在图像视图中设置图像,并且在横向模式下显示预览时,我会获得像图标一样的非常小的位图。请帮帮我。 – 2014-08-29 13:03:37

相关问题