当我在Android One手机或仿真器上测试我的应用程序时,一切正常,但是有一些其他设备存在问题。
问题是,我基本上发送了一个摄像头意图,在用户拍照后从意图中获取数据,并设置ImageView
的像素与我从相机获得的任何内容。对于某些设备(主要是三星),图像会旋转,因此不会显示图像。
我的应用程序仅在纵向模式下工作,但如果用户在拍摄图像时旋转手机,也可以在横向模式下拍照。
有没有办法检测设备旋转图像的默认角度,所以我在拍摄图像后旋转位图?
以下是代码:
发送意图:
File path = new File(getActivity().getFilesDir(), "map_roomie");
if (!path.exists()) path.mkdirs();
mFileName = createImageFileName();
File image = new File(path, mFileName);
Uri imageUri = FileProvider.getUriForFile(getActivity(), AddRoomFragment.CAPTURE_IMAGE_FILE_PROVIDER, image);
Intent imageCaptureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
imageCaptureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(imageCaptureIntent, AddRoomFragment.CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
捕获片段上的意图
File path = new File(getActivity().getFilesDir(), "map_roomie");
if (!path.exists()) path.mkdirs();
File imageFile = new File(path, mFileName);
setBitmapOfImageView(mCurrentPhotoId, decodeAndReturnBitmap(imageFile.getAbsolutePath()));
辅助函数:
public void setBitmapOfImageView(int photoId, Bitmap bitmap)
{
mPhotos[photoId].setImageBitmap(bitmap);
mPhotosState[photoId] = 1;
}
public Bitmap decodeAndReturnBitmap(String filePath)
{
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, o);
final int REQUIRED_SIZE = 512;
int widthTemp = o.outWidth, heightTemp = o.outHeight;
int scale = 1;
while (true) {
if (widthTemp < REQUIRED_SIZE && heightTemp < REQUIRED_SIZE) {
break;
}
widthTemp /= 2;
heightTemp /= 2;
scale *= 2;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeFile(filePath, o2);
}
答案 0 :(得分:2)
如果要使摄像机图像以与显示屏相同的方向显示,可以使用以下代码。
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);
}
有关详细信息,请参阅https://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int)
答案 1 :(得分:1)
this solution work properly for me.
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);
}
答案 2 :(得分:0)
请看看 -
private int getCameraId() {
int curCameraId = 0;
if (Camera.getNumberOfCameras() > 0) {
curCameraId = (curCameraId + 1) % Camera.getNumberOfCameras();
} else {
curCameraId = 0;
}
return curCameraId;
}
public void setCameraDisplayOrientation(Activity activity, int curCameraId) {
if (camera == null) {
try {
camera = Camera.open(curCameraId);
} catch (Exception e) {
}
}
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(curCameraId, info);
WindowManager winManager = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
int rotation = winManager.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);
}
答案 3 :(得分:0)
我使用ExifInterface修复了这个问题。但是,如果有人能够在拍照时检测出在图像上应用的默认角度,那将会很棒。
以下是代码:
public Bitmap decodeAndReturnBitmap(String filePath)
{
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, o);
final int REQUIRED_SIZE = 512;
int widthTemp = o.outWidth, heightTemp = o.outHeight;
int scale = 1;
while (true) {
if (widthTemp < REQUIRED_SIZE && heightTemp < REQUIRED_SIZE) {
break;
}
widthTemp /= 2;
heightTemp /= 2;
scale *= 2;
}
ExifInterface exifInterface = null;
try {
exifInterface = new ExifInterface(filePath);
} catch (IOException e) {
e.printStackTrace();
}
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
Matrix matrix = new Matrix();
switch(orientation) {
case ExifInterface.ORIENTATION_ROTATE_90 :
matrix.setRotate(90.0f);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.setRotate(180.0f);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.setRotate(270.0f);
break;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
Bitmap bitmap = BitmapFactory.decodeFile(filePath, o2);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}