У меня есть Android приложение, записанное в Java, которое делает снимок с помощью приложения камеры, а затем сохраняет его в виде файла. На Android KitKat и Lollipop все работает хорошо, но на Android 10 (Q) сохраненный файл больше похож на миниатюру, чем на картинку большого размера.
Чтобы сделать снимок, я следовал инструкциям Android веб-сайт разработчиков: https://developer.android.com/training/camera/photobasics
Код для запуска намерения:
private void captureImage() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri uri;
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
if (photoFile == null) {
return;
}
uri = FileProvider.getUriForFile(this, this.getApplicationContext().getPackageName() + ".provider", photoFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
intent.addFlags(FLAG_GRANT_WRITE_URI_PERMISSION);
intent.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
} else {
List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
grantUriPermission(packageName, uri, FLAG_GRANT_WRITE_URI_PERMISSION | FLAG_GRANT_READ_URI_PERMISSION);
}
}
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, CAMERA_REQUEST_CODE);
}
}
А мой код для декодирования изображения выглядит следующим образом:
public static Bitmap decodeSampledBitmapFromFile(String path, int imgWidth, int imgHeight) {
Log.e("test image", "debut decodeSampledBitmapFromFile");
//First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize, Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
Log.e("test image", "imgHeight =" + imgHeight + ", imgWidth =" + imgWidth);
Log.e("test image", "height =" + height + ", width =" + width);
options.inPreferredConfig = Bitmap.Config.RGB_565;
int inSampleSize = 1;
if (height > imgHeight) {
inSampleSize = Math.round((float) height / (float) imgHeight);
}
Log.e("test", "inSampleSize =" + inSampleSize);
int expectedWidth = width / inSampleSize;
Log.e("test", "expectedWidth =" + expectedWidth);
if (expectedWidth > imgWidth) {
//if(Math.round((float)width / (float)reqWidth) > inSampleSize) // If bigger SampSize..
inSampleSize = Math.round((float) width / (float) imgWidth);
}
Log.e("test", "inSampleSize =" + inSampleSize);
options.inSampleSize = inSampleSize;
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
Log.e("test image", "fin decodeSampledBitmapFromFile");
return BitmapFactory.decodeFile(path, options);
}
Тогда код для вызова вышеуказанного метода выглядит следующим образом:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Résultat de la capture de la photo
if (requestCode == CAMERA_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
Bitmap imageBitmap1 = null;
// File file = new File(Environment.getExternalStorageDirectory() + File.separator + "image.jpg");
File file = new File(currentPhotoPath);
Matrix matrix = null;
try {
ExifInterface exif = new ExifInterface(file.getPath());
int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int rotationInDegrees = exifToDegrees(rotation);
matrix = new Matrix();
if (rotation != 0f) {matrix.preRotate(rotationInDegrees);}
if(rotationInDegrees == 90){
imageBitmap1 = Utils.decodeSampledBitmapFromFile(file.getAbsolutePath(), 500, 800);
}else{
imageBitmap1 = Utils.decodeSampledBitmapFromFile(file.getAbsolutePath(), 800, 500);
}
} catch (IOException e) {
e.printStackTrace();
}
imageBitmap = Bitmap.createBitmap(imageBitmap1, 0, 0, imageBitmap1.getWidth(), imageBitmap1.getHeight(), matrix, true);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 50, stream);
inputPhoto = stream.toByteArray();
Журналы на KitKat: imgHeight = 500, imgWidth = 800, высота = 3264, ширина = 2448, inSampleSize = 7, ожидаемая ширина = 349, inSampleSize = 7
Журналы Q: imgHeight = 800, imgWidth = 500, высота = 3376, ширина = 5984, inSampleSize = 4, ожидаемая ширина = 1496, inSampleSize = 12