Я работаю над приложением для Android, которое управляет пациентами.В приложении есть возможность захвата изображения пациента с камеры - и это изображение загружается в облако базы данных.Я решил сжать изображения, прежде чем загружать их в Firebase.До сих пор все работало нормально, но по какой-то причине после сжатия изображения (следуя инструкциям здесь: http://voidcanvas.com/whatsapp-like-image-compression-in-android/) я получаю много ошибок ...
Изображение сжимается успешно, и когдая пытаюсь установить ImageView на Uri фотографии, это работает, но когда я использую glide, это не работает :( Кроме того, когда я пытаюсь загрузить изображение в хранилище Firebase позже, это дает мне No Content ProvidorОшибка.
Я думаю, что ошибка исходит из сгенерированного имени файла, в функции сжатия изображения - но я не знаю, что изменить, и что вызывает ошибку ...
Вкл.С другой стороны, если у кого-то есть более простой метод сжатия изображений, который использует URI изображения контента (который был передан из провайдера файла), я всегда буду в долгу!
Большое спасибо!
Призыв к сжатию захваченного изображения:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d("request_code", String.valueOf(requestCode));
if (requestCode == Constants.REQUEST_PATIENT_IMAGE_CAPTURE) {
if (resultCode == RESULT_OK) {
//Previously was just patientImage.setImageUri(newPatientImage)
Uri tempImage = ImageHandler.compressImage(newPatientImage);
// Glide.with(PatientCardActivity.getInstance())
// .load(tempImage)
// .fitCenter()
// .error(R.drawable.no_image_icon)
// .fallback(R.drawable.empty_user)
// .into(patientImage);
patientImage.setImageURI(tempImage);
newPatientImage = tempImage;
changedSuccess = true;
}
else newPatientImage = null;
}
Как сгенерировать Uri для сжатого файла:
protected static File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Constants.EXTERNAL_FILES_DIR;
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
return image;
}
protected static Uri createImageUri() {
Uri photoURI = Uri.parse("");
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
photoFile.delete();
}
// Error occurred while creating the File
// Continue only if the File was successfully created
if (photoFile != null) {
photoURI = Uri.fromFile(photoFile.getAbsoluteFile());
}
return photoURI;
}
Функция сжатия изображения:
public static Uri compressImage(Uri imageUri) {
if (imageUri == null)
return imageUri;
Bitmap scaledBitmap = null;
Bitmap bmp = null;
BitmapFactory.Options options = new BitmapFactory.Options();
ContentResolver cr = PatientCardActivity.getInstance().getContentResolver();
try {
InputStream is = cr.openInputStream(imageUri);
// by setting this field as true, the actual bitmap pixels are not loaded in the memory. Just the bounds are loaded. If
// you try the use the bitmap here, you will get null.
options.inJustDecodeBounds = true;
bmp = BitmapFactory.decodeStream(is, null, options);
if (is != null) {
is.close();
}
}
catch (Exception e){
e.printStackTrace();
}
int actualHeight = options.outHeight;
int actualWidth = options.outWidth;
float maxHeight = 816.0f;
float maxWidth = 612.0f;
float imgRatio = actualWidth / actualHeight;
float maxRatio = maxWidth / maxHeight;
if (actualHeight > maxHeight || actualWidth > maxWidth) {
if (imgRatio < maxRatio) {
imgRatio = maxHeight / actualHeight;
actualWidth = (int) (imgRatio * actualWidth);
actualHeight = (int) maxHeight;
} else if (imgRatio > maxRatio) {
imgRatio = maxWidth / actualWidth;
actualHeight = (int) (imgRatio * actualHeight);
actualWidth = (int) maxWidth;
} else {
actualHeight = (int) maxHeight;
actualWidth = (int) maxWidth;
}
}
options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight);
options.inJustDecodeBounds = false;
options.inPurgeable = true;
options.inInputShareable = true;
options.inTempStorage = new byte[16 * 1024];
try {
InputStream is = cr.openInputStream(imageUri);
bmp = BitmapFactory.decodeStream(is, null, options);
} catch (Exception e) {
e.printStackTrace();
}
try {
scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
} catch (OutOfMemoryError exception) {
exception.printStackTrace();
}
float ratioX = actualWidth / (float) options.outWidth;
float ratioY = actualHeight / (float) options.outHeight;
float middleX = actualWidth / 2.0f;
float middleY = actualHeight / 2.0f;
Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
Canvas canvas = new Canvas(scaledBitmap);
canvas.setMatrix(scaleMatrix);
canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new
Paint(Paint.FILTER_BITMAP_FLAG));
FileOutputStream out = null;
String filename = createImageUri().getPath();
try {
out = new FileOutputStream(filename);
// write the compressed bitmap at the destination specified by filename.
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return Uri.parse(filename);
}
Функция, котораязагружает изображение в базу:
protected static String uploadImageToStorage(String imagesFolderName, String uid, Uri imageUri){
String storagePath = imagesFolderName + Constants.DATABASE_SEP_CHAR +
createStorageImageName(uid, imageUri);
StorageReference imageRef = storageRef.child(storagePath);
UploadTask uploadTask = imageRef.putFile(imageUri);
final Boolean [] completedSuccessfully = {true};
// Register observers to listen for when the download is done or if it fails
uploadTask.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
//TODO Handle unsuccessful uploads
completedSuccessfully[0] = false;
Log.d("UnSuccessfull upload", exception.toString());
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// taskSnapshot.getMetadata() contains file metadata such as size, content-type, etc.
// ...
}
});
if (completedSuccessfully[0])
return storagePath;
else
return "";
}
Ошибка, которую я получаю:
E/UploadTask: could not locate file for
uploading:/storage/emulated/0/Android/data/com.example.myapp/files/Pictures/JPEG_20190929_123827_6249547593857539634.jpg
E/StorageException: StorageException has occurred.
An unknown error occurred, please check the HTTP result code and inner exception for server response.
Code: -13000 HttpResult: 0
E/StorageException: No content provider: /storage/emulated/0/Android/data/com.example.myapp/files/Pictures/JPEG_20190929_123827_6249547593857539634.jpg
java.io.FileNotFoundException: No content provider: /storage/emulated/0/Android/data/com.example.myapp/files/Pictures/JPEG_20190929_123827_6249547593857539634.jpg
at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1451)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1302)
at android.content.ContentResolver.openInputStream(ContentResolver.java:1022)
at com.google.firebase.storage.UploadTask.<init>(com.google.firebase:firebase-storage@@19.0.1:131)
at com.google.firebase.storage.StorageReference.putFile(com.google.firebase:firebase-storage@@19.0.1:251)
at com.example.myapp.UploadDownload.uploadImageToStorage(UploadDownload.java:136)
at com.example.myapp.UploadDownload.uploadPatientImage(UploadDownload.java:215)
at com.example.myapp.UploadDownload.updatePatient(UploadDownload.java:184)
at com.example.myapp.PatientCardActivity.addInfo(PatientCardActivity.java:476)
at com.example.myapp.PatientCardActivity.addInfo(PatientCardActivity.java:410)
at com.example.myapp.PatientCardActivity.access$1800(PatientCardActivity.java:58)
at com.example.myapp.PatientCardActivity$8.onClick(PatientCardActivity.java:285)
at android.view.View.performClick(View.java:7352)
at android.view.View.performClickInternal(View.java:7318)
at android.view.View.access$3200(View.java:846)
at android.view.View$PerformClick.run(View.java:27801)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7045)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)
E/StorageException: StorageException has occurred.