tccpg288
tccpg288

Reputation: 3352

Load Image (Not Bitmap Thumbnail) From Android Camera Intent

I am using the camera intent to allow users to take pictures and upload images to Firebase storage. I am noticing that during this process, considerable image quality is being lost since I am pulling the bitmap and not the actual image file. I would obviously like to limit file size and compress where necessary, however I would like to retain original image quality as well. Here is where I call the camera intent and prompt the user to take a photo:

 case 1:
          Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
          if (takePictureIntent.resolveActivity(getApplication().getPackageManager()) != null) {
          startActivityForResult(takePictureIntent, TAKE_PICTURE);
         } else {Toast.makeText(getApplicationContext(), getResources().getString(R.string.camera_error), Toast.LENGTH_LONG).show();
                            }
         break;

Here is the .onActivityResult() method where I retrieve the image data:

  case TAKE_PICTURE:
            //TODO: Limit file size to prevent reaching Firebase storage limit
            if (resultCode == CreateActivity.RESULT_OK) {
                Bundle extras = data.getExtras();
                Bitmap imageBitmap = (Bitmap) extras.get("data");
                mImagePreview.setDrawingCacheEnabled(true);
                mImagePreview.buildDrawingCache();
                mImagePreview.setImageBitmap(imageBitmap);
                encodeBitmapAndSaveToFirebase(imageBitmap);
            }
            break;

And save to Firebase:

private void encodeBitmapAndSaveToFirebase(Bitmap bitmap) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    byte[] data = baos.toByteArray();

    String uniqueID = java.util.UUID.randomUUID().toString();
    mFileRef = mStorageRef.child(uniqueID);
    UploadTask uploadTask = mFileRef.putBytes(data);
    uploadTask.addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception exception) {
            Toast.makeText(getApplicationContext(), "Error Loading Photo", Toast.LENGTH_LONG).show();
        }
    }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
            // taskSnapshot.getMetadata() contains file metadata such as size, content-type, and download URL.
            Uri downloadUrl = taskSnapshot.getDownloadUrl();
            resultImageURL = downloadUrl.toString();
            Picasso.with(getApplicationContext())
                    .load(resultImageURL)
                    .into(mImagePreview);
        }
    });

}

Upvotes: 0

Views: 1023

Answers (2)

Doug Stevenson
Doug Stevenson

Reputation: 317487

The Google tutorial for taking a picture in Android using an external camera app is this: https://developer.android.com/training/camera/photobasics.html

If you follow that example, you will have created a file where the camera app will save the image data. If you don't want to lose any quality in the image, upload the contents of that file directly. As it stands now, you are uploading the thumbnail of the image, which is going to be nowhere near the size and quality of the source image.

Upvotes: 1

Arpit Jain
Arpit Jain

Reputation: 104

Here, quality => The quality we want our picture to have on a scale of 1 – 100. targetWidth & targetHeight => This gives you the image size in px.

takePicture(){
  Camera.getPicture({
   quality : 95,
   destinationType : Camera.DestinationType.DATA_URL,
   sourceType : Camera.PictureSourceType.CAMERA,
   allowEdit : true,
   encodingType: Camera.EncodingType.PNG,
   targetWidth: 500,
   targetHeight: 500,
   saveToPhotoAlbum: true
 }).then(imageData => {
   this.guestPicture = imageData;
 }, error => {
   console.log("ERROR -> " + JSON.stringify(error));
  });
}

Upvotes: 2

Related Questions