I am trying to Compress an Image before Uploading it to Firebase Storage
using SiliCompressor
library , but it seems not working , the ProgressD
I have done this way:
private void startPosting() {
mProgress.setMessage(getString(R.string.downloading_route));
final String titleVal = mRouteTitle.getText().toString().trim();
final String descVal = mRouteDesc.getText().toString().trim();
if (!TextUtils.isEmpty(titleVal) && !TextUtils.isEmpty(descVal) && mImageUri != null) {
mProgress.show();
StorageReference filepath = mStorage.child("Route images").child(mImageUri.getLastPathSegment());
//compress image
mSelectImage.setDrawingCacheEnabled(true);
mSelectImage.buildDrawingCache();
Bitmap bitmap = mSelectImage.getDrawingCache();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, byteArrayOutputStream);
byte[] data = byteArrayOutputStream.toByteArray();
UploadTask uploadTask = filepath.putBytes(data);
uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
@SuppressWarnings("VisibleForTests")
final Uri downloadUrl = taskSnapshot.getDownloadUrl();
final DatabaseReference newPost = mDatabase.push();
mDatabaseUser.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
newPost.child("title").setValue(titleVal);
newPost.child("desc").setValue(descVal);
newPost.child("image").setValue(downloadUrl.toString());
newPost.child("uid").setValue(mCurrentUser.getUid());
newPost.child("username").setValue(dataSnapshot.child("name").getValue()).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
startActivity(new Intent(AddRouteActivity.this, MainActivity.class));
}
});
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
mProgress.dismiss();
}
});
}
}
//declear local variable first
Bitmap bitmap; Uri imageUri;
//button action to call Image picker method
ImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Pick Image"),GALLERY_REQ_CODE);
}
});
//get bitmap from onActivityResult
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == GALLERY_REQ_CODE && resultCode == RESULT_OK && data != null) {
imageUri = data.getData();
try {
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
} catch (IOException e) {
e.printStackTrace();
}
imageView.setImageURI(imageUri);
}
}
//compress image first then upload to firebase
public void postImage() {
StorageReference storageReference = mStorageRef.child("Images/" + //imageName);
databaseReference = FirebaseDatabase.getInstance().getReference().child("Jobs").child(//imageName);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 20, bytes);
String path = MediaStore.Images.Media.insertImage(SaveJobActivity.this.getContentResolver(),bitmap,//imageName,null);
Uri uri = Uri.parse(path);
storageReference.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
taskSnapshot.getStorage().getDownloadUrl().addOnCompleteListener(new OnCompleteListener<Uri>() {
@Override
public void onComplete(@NonNull Task<Uri> task) {
final String downloadUrl = task.getResult().toString();
if (task.isSuccessful()){
Map<String, Object> update_hashMap = new HashMap<>();
**//assign download url in hashmap to upadate database reference**
update_hashMap.put("Image",downloadUrl);
**//update database children here**
databaseReference.updateChildren(update_hashMap).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()){
//do what you want
}else {
//show exception
}
}
});
}else{
//show exception
}
}
});
}
});
}
Here is what I have written, you can try it.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == Constants.PICK_USER_PROFILE_IMAGE) {
if (resultCode == RESULT_OK) {
Bitmap bmp = ImagePicker.getImageFromResult(this, resultCode, data);//your compressed bitmap here
startPosting(bmp);
}
}
}
}
Your startPosting method should be like this
private void startPosting(Bitmap bmp) {
byte[] data = bmp.toByteArray();
mProgress.setMessage("Uploading Image...");
final String title_val = mPostTitle.getText().toString().trim();
final String desc_val = mPostDesc.getText().toString().trim();
if (!TextUtils.isEmpty(title_val) && !TextUtils.isEmpty(desc_val) && filePath != null) {
mProgress.show();
StorageReference filepath = mStorage.child("BlogImages").child(uri_image_final.getLastPathSegment());
UploadTask uploadTask = filepath.putBytes(data);
uploadTask.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
// Handle unsuccessful uploads
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Uri downloadUri = taskSnapshot.getDownloadUrl();
DatabaseReference newPost = mDatabase.push();
DatabaseReference c = mDatabase.push();
newPost.child("EventTitle").setValue(title_val);
newPost.child("EventDescription").setValue(desc_val);
newPost.child("EventImage").setValue(downloadUri.toString());
newPost.child("PostId").setValue(c);
mProgress.dismiss();
startActivity(new Intent(PostActivity.this, MainActivity.class));
}
});
} else if (TextUtils.isEmpty(title_val) && TextUtils.isEmpty(desc_val) && imageUri != null) {
mProgress.show();
StorageReference filepath = mStorage.child("BlogImages").child(uri_image_final.getLastPathSegment());
UploadTask uploadTask = filepath.putBytes(data);
uploadTask.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
// Handle unsuccessful uploads
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Uri downloadUri = taskSnapshot.getDownloadUrl();
DatabaseReference newPost = mDatabase.push();
newPost.child("EventTitle").setValue("");
newPost.child("EventDescription").setValue("");
newPost.child("EventImage").setValue(downloadUri.toString());
mProgress.dismiss();
// startActivity(new Intent(PostActivity.this, MainActivity.class));
Intent load= new Intent(PostActivity.this,MainActivity.class);
load.putExtra(eventname,eventname);
startActivity(load);
}
});
}
else if (!TextUtils.isEmpty(title_val) && !TextUtils.isEmpty(desc_val) && imageUri== null){
Toast.makeText(getApplicationContext(),"Please insert an Image and Upload ! ",Toast.LENGTH_LONG).show();
}
}
Below is the class ImagePicker that have series of methods to do your work
public class ImagePicker {
private static final int DEFAULT_MIN_WIDTH_QUALITY = 400; // min pixels
private static final String TAG = "ImagePicker";
private static final String TEMP_IMAGE_NAME = "tempImage";
public static int minWidthQuality = DEFAULT_MIN_WIDTH_QUALITY;
public static Bitmap getImageFromResult(Context context, int resultCode,
Intent imageReturnedIntent) {
Log.d(TAG, "getImageFromResult, resultCode: " + resultCode);
Bitmap bm = null;
File imageFile = getTempFile(context);
if (resultCode == Activity.RESULT_OK) {
Uri selectedImage;
boolean isCamera = (imageReturnedIntent == null ||
imageReturnedIntent.getData() == null ||
imageReturnedIntent.getData().equals(Uri.fromFile(imageFile)));
if (isCamera) { /** CAMERA **/
selectedImage = Uri.fromFile(imageFile);
} else { /** ALBUM **/
selectedImage = imageReturnedIntent.getData();
}
Log.d(TAG, "selectedImage: " + selectedImage);
bm = getImageResized(context, selectedImage);
int rotation = getRotation(context, selectedImage, isCamera);
bm = rotate(bm, rotation);
}
return bm;
}
private static Bitmap decodeBitmap(Context context, Uri theUri, int sampleSize) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = sampleSize;
AssetFileDescriptor fileDescriptor = null;
try {
fileDescriptor = context.getContentResolver().openAssetFileDescriptor(theUri, "r");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Bitmap actuallyUsableBitmap = BitmapFactory.decodeFileDescriptor(
fileDescriptor.getFileDescriptor(), null, options);
Log.d(TAG, options.inSampleSize + " sample method bitmap ... " +
actuallyUsableBitmap.getWidth() + " " + actuallyUsableBitmap.getHeight());
return actuallyUsableBitmap;
}
/**
* Resize to avoid using too much memory loading big images (e.g.: 2560*1920)
**/
private static Bitmap getImageResized(Context context, Uri selectedImage) {
Bitmap bm = null;
int[] sampleSizes = new int[]{5, 3, 2, 1};
int i = 0;
do {
bm = decodeBitmap(context, selectedImage, sampleSizes[i]);
Log.d(TAG, "resizer: new bitmap width = " + bm.getWidth());
i++;
} while (bm.getWidth() < minWidthQuality && i < sampleSizes.length);
return bm;
}
private static int getRotation(Context context, Uri imageUri, boolean isCamera) {
int rotation;
if (isCamera) {
rotation = getRotationFromCamera(context, imageUri);
} else {
rotation = getRotationFromGallery(context, imageUri);
}
Log.d(TAG, "Image rotation: " + rotation);
return rotation;
}
private static int getRotationFromCamera(Context context, Uri imageFile) {
int rotate = 0;
try {
context.getContentResolver().notifyChange(imageFile, null);
ExifInterface exif = new ExifInterface(imageFile.getPath());
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
} catch (Exception e) {
e.printStackTrace();
}
return rotate;
}
public static int getRotationFromGallery(Context context, Uri imageUri) {
String[] columns = {MediaStore.Images.Media.ORIENTATION};
Cursor cursor = context.getContentResolver().query(imageUri, columns, null, null, null);
if (cursor == null) return 0;
cursor.moveToFirst();
int orientationColumnIndex = cursor.getColumnIndex(columns[0]);
return cursor.getInt(orientationColumnIndex);
}
private static Bitmap rotate(Bitmap bm, int rotation) {
if (rotation != 0) {
Matrix matrix = new Matrix();
matrix.postRotate(rotation);
Bitmap bmOut = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
return bmOut;
}
return bm;
}
private static File getTempFile(Context context) {
File imageFile = new File(context.getExternalCacheDir(), TEMP_IMAGE_NAME);
imageFile.getParentFile().mkdirs();
return imageFile;
}
}
The ImagePicker Class have all the methods of handling compression as well as rotation of image.
Hope it will help
Thanks to this link for uploading file ref
Uploading files on firebase