我需要一种在捕获照片后自动旋转图片的方法。
它需要自动拾取旋转并进行校正。
当我拍照时,它会逆时针旋转90度。
private void CompressAndSetImage(Uri uri)
{
Bitmap thumbnail = null;
try {
thumbnail = MediaStore.Images.Media.getBitmap(getActivity().getApplicationContext().getContentResolver(), uri);
int nh = (int) ( thumbnail.getHeight() * (1024.0 / thumbnail.getWidth()) );
Bitmap scaled = Bitmap.createScaledBitmap(thumbnail, 1024, nh, true);
Bitmap squareImage = cropToSquare(scaled);
CurrImageURI = getImageUri(getActivity().getApplicationContext(), squareImage);
iv_child.setImageURI(CurrImageURI);
isImageUploaded = true;
} catch (IOException e) {
Toast.makeText(getContext(), "Some error occured", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
private Bitmap cropToSquare(Bitmap bitmap){
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int newWidth = (height > width) ? width : height;
int newHeight = (height > width)? height - ( height - width) : height;
int cropW = (width - height) / 2;
cropW = (cropW < 0)? 0: cropW;
int cropH = (height - width) / 2;
cropH = (cropH < 0)? 0: cropH;
Bitmap cropImg = Bitmap.createBitmap(bitmap, cropW, cropH, newWidth, newHeight);
return cropImg;
}
private Uri getImageUri(Context inContext, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
return Uri.parse(path);
}
谢谢。
答案 0 :(得分:0)
如果您是出于意图打开相机,则解决旋转问题的最佳方法是在临时片段上放置旋转图标。让用户旋转图像本身并将其发布到您的最终图像视图中。
您还可以使用Android cameraX api创建自定义相机,这是Camera2 Api的包装器类,借助 setTargetRotation 您可以解决相机旋转问题。
答案 1 :(得分:0)
ExifInterface
From official doc:
这是用于在JPEG文件或 RAW图像文件。支持的格式有:JPEG,DNG,CR2,NEF,NRW,ARW, RW2,ORF,PEF,SRW,RAF和HEIF。
图像旋转通常作为图像文件的一部分存储在照片的Exif数据中。您可以使用Android ExifInterface读取图像的Exif元数据
您可以使用此类来获取从默认图像库中选择的图像的正确方向。
在您的应用中应用以下代码:
首先使用当前上下文和要修复的图像URI调用以下方法。
public static Bitmap handleSamplingAndRotationBitmap(Context context, Uri selectedImage)
throws IOException {
int MAX_HEIGHT = 1024;
int MAX_WIDTH = 1024;
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
InputStream imageStream = context.getContentResolver().openInputStream(selectedImage);
BitmapFactory.decodeStream(imageStream, null, options);
imageStream.close();
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, MAX_WIDTH, MAX_HEIGHT);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
imageStream = context.getContentResolver().openInputStream(selectedImage);
Bitmap img = BitmapFactory.decodeStream(imageStream, null, options);
img = rotateImageIfRequired(img, selectedImage);
return img;
}
CalculateInSampleSize方法:
private static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
// Calculate ratios of height and width to requested height and width
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
// Choose the smallest ratio as inSampleSize value, this will guarantee a final image
// with both dimensions larger than or equal to the requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
final float totalPixels = width * height;
// Anything more than 2x the requested pixels we'll sample down further
final float totalReqPixelsCap = reqWidth * reqHeight * 2;
while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
inSampleSize++;
}
}
return inSampleSize;
}
然后是检查当前图像方向以确定旋转角度的方法:
private static Bitmap rotateImageIfRequired(Bitmap img, Uri selectedImage) throws IOException {
ExifInterface ei = new ExifInterface(selectedImage.getPath());
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
return rotateImage(img, 90);
case ExifInterface.ORIENTATION_ROTATE_180:
return rotateImage(img, 180);
case ExifInterface.ORIENTATION_ROTATE_270:
return rotateImage(img, 270);
default:
return img;
}
}
最后是旋转方法本身:
private static Bitmap rotateImage(Bitmap img, int degree) {
Matrix matrix = new Matrix();
matrix.postRotate(degree);
Bitmap rotatedImg = Bitmap.createBitmap(img, 0, 0, img.getWidth(), img.getHeight(), matrix, true);
img.recycle();
return rotatedImg;
}
此代码的来源:doc