我正在开发用于管理患者的android应用。在该应用程序中,可以从相机捕获患者图像-并将该图像上传到Firebase云。 我决定先压缩图像,然后再将其上传到Firebase。到目前为止,一切正常,但是由于压缩图像后的某种原因(遵循指南http://voidcanvas.com/whatsapp-like-image-compression-in-android/),我遇到了很多错误...
图像已成功压缩,当我尝试将ImageView设置为照片的Uri时,它可以工作,但是当我使用滑行进行操作时,它不起作用:( 另外,当我稍后尝试将图像上传到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);
}
将图像上传到Firebase的功能:
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.