How to fix bitmap resizing the captured image in android

449 views Asked by At

My Photo Editor Android application has some issue. After capturing the image from the 20MegaPixel (5184x3880) camera through the app, I am resizing the image through Bitmap to 15MegaPixel (4477 x 3351) and then saving the image in the Gallery/Photos folder in the phone

Following is the HomeActivity code:

package com.saashtechs.photoeditor;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.Media;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.util.Date;
import java.util.Objects;
import java.io.InputStream;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;

import static android.Manifest.permission.CAMERA;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;

public class HomeActivity extends AppCompatActivity {

    private static final String TAG = "HomeActivity";
    private static final int GALLERY_RESULT = 1;
    private static final int CAMERA_RESULT = 2;
    private static final String FILE_PROVIDER_AUTHORITY = "com.saashtechs.photoeditor";
    private static final int CAMERA_PERMISSION_REQ_CODE = 1001;
    private static final int STORAGE_PERMISSION_REQ_CODE = 1002;
    private Uri imageToUploadUri;
    private String mCapturedImagePath;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
    }

    public void openCamera(View view) {
        // check for camera permission if not granted before
        if (ContextCompat.checkSelfPermission(this, CAMERA) != PERMISSION_GRANTED) {
            String[] cameraPermission = {CAMERA};
            ActivityCompat.requestPermissions(this, cameraPermission, CAMERA_PERMISSION_REQ_CODE);
        } else {
            dispatchImageCaptureIntent();
        }
    }

    public void openGallery(View view) {
        // check for storage permission if not granted before
        if (ContextCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE) != PERMISSION_GRANTED ||
                ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE) != PERMISSION_GRANTED) {
            String[] storagePermissions = {READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE};
            ActivityCompat.requestPermissions(this, storagePermissions, STORAGE_PERMISSION_REQ_CODE);
        } else {
            dispatchGalleryIntent();
        }
    }

    private void dispatchGalleryIntent() {
        Intent galleryIntent = new Intent(Intent.ACTION_PICK, Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(galleryIntent, GALLERY_RESULT);
    }

    private void dispatchImageCaptureIntent() {
        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (cameraIntent.resolveActivity(getPackageManager()) != null) {
            File photoFile = null;
            try {
                photoFile = createImageFile();
            } catch (IOException e) {
                e.printStackTrace();
            }

            if (photoFile != null) {
                Uri photoFileUri = FileProvider.getUriForFile(this, FILE_PROVIDER_AUTHORITY, photoFile);
                Log.d(TAG, "dispatchImageCaptureIntent:photoFileUri: " + photoFile.toString());
                //Add URI to imageToUploadUri. You forgot to add it.
                imageToUploadUri = photoFileUri;
                cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoFileUri);
                startActivityForResult(cameraIntent, CAMERA_RESULT);
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case CAMERA_PERMISSION_REQ_CODE:
                if (grantResults[0] == PERMISSION_GRANTED) {
                    dispatchImageCaptureIntent();
                } else {
                    Toast.makeText(this, "Required camera permission not granted", Toast.LENGTH_SHORT).show();
                }
                break;

            case STORAGE_PERMISSION_REQ_CODE:
                if (grantResults[0] == PERMISSION_GRANTED) {
                    dispatchGalleryIntent();
                } else {
                    Toast.makeText(this, "Required storage permission not granted", Toast.LENGTH_SHORT)
                            .show();
                }
                break;

            default:
                throw new IllegalArgumentException("Unexpected request code");
        }
    }

    private File createImageFile() throws IOException {
        String timeStamp = DateFormat.getDateTimeInstance().format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(imageFileName, ".jpg", storageDir);
        mCapturedImagePath = image.getAbsolutePath();
        Log.d(TAG, "createImageFile: " + mCapturedImagePath);
        return image;
    }

    private Bundle uriToBundle(Uri imageUri) {
        Bundle bundle = new Bundle();
        bundle.putString(MainActivity.IMAGE_URI, imageUri.toString());
        return bundle;
    }

    public Bitmap resizeBitmap(Bitmap getBitmap, int maxSize) {
        int width = getBitmap.getWidth();//5184
        int height = getBitmap.getHeight();//3880
        double resized_image;

        if (width >= height && width > maxSize) {
            resized_image = width / height;
            width = maxSize;
            height = (int) (maxSize / resized_image);
        } else if (height >= width && height > maxSize) {
            resized_image = height / width;
            height = maxSize;
            width = (int) (maxSize / resized_image);
        }
        return Bitmap.createScaledBitmap(getBitmap, width, height, false);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            if (requestCode == GALLERY_RESULT) {
                Uri imageUri = data.getData();
                startActivity(MainActivity.getIntent(this, uriToBundle(Objects.requireNonNull(imageUri))));
            } else if (requestCode == CAMERA_RESULT) {
                File imageFile = new File(mCapturedImagePath);
                Bitmap image = BitmapFactory.decodeFile(mCapturedImagePath);
                image = Bitmap.createScaledBitmap(image, 4477, 3351, false);
                image = resizeBitmap(image, 4477);
                ByteArrayOutputStream bytes = new ByteArrayOutputStream();
                image.compress(Bitmap.CompressFormat.JPEG, 100, bytes);

                try {
                    File file = new File(Environment.getExternalStorageDirectory() + File.separator + "filename.jpg");
                    boolean result;
                    result = file.createNewFile();
                    if (result) {
                        FileOutputStream fo = new FileOutputStream(imageFile);
                        fo.write(bytes.toByteArray());
                        fo.close();
                    }
                } catch(IOException ie) {
                    ie.printStackTrace();
                }

                startActivity(MainActivity.getIntent(this, uriToBundle(Objects.requireNonNull(imageToUploadUri))));
            }
        } else {
            Toast.makeText(this, "Image not loaded.", Toast.LENGTH_SHORT).show();
        }
    }

    public static Intent getIntent(Context context) {
        return new Intent(context, HomeActivity.class);
    }
}

Following is the MainActivity code:

package com.saashtechs.photoeditor;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ImageView;
import com.adobe.creativesdk.aviary.AdobeImageIntent;

public class MainActivity extends AppCompatActivity {

  public static final String IMAGE_URI = "IMAGE_URI_KEY";

  private static final String TAG = "MainActivity";
  private static final int IMAGE_EDITOR_RESULT = 1;

  private ImageView mEditedImageView;

  @Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mEditedImageView = (ImageView) findViewById(R.id.edited_image_view);

    Bundle extras = getIntent().getExtras();
    if (extras != null) {
      Uri imageUri = Uri.parse(getIntent().getExtras().getString(IMAGE_URI));
      Intent imageEditorIntent = new AdobeImageIntent.Builder(this).setData(imageUri).build();
      startActivityForResult(imageEditorIntent, IMAGE_EDITOR_RESULT);
      finish(); 
    }
  }

  @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK) {
      switch (requestCode) {
        case IMAGE_EDITOR_RESULT:
          Uri editedImageUri = data.getParcelableExtra(AdobeImageIntent.EXTRA_OUTPUT_URI);
          Log.d(TAG, "editedImageUri: " + editedImageUri.toString());
          Bundle extra = data.getExtras();
          if (extra != null) {
            boolean changed = extra.getBoolean(AdobeImageIntent.EXTRA_OUT_BITMAP_CHANGED);
            Log.d(TAG, "Image edited: " + changed);
            if (changed) {
              mEditedImageView.setImageURI(editedImageUri);
            }
          }
          break;

        default:
          throw new IllegalArgumentException("Unexpected request code");
      }
    }
  }

  public static Intent getIntent(Context context, Bundle bundle) {
    Intent intent = new Intent(context, MainActivity.class);
    if (bundle != null) {
      intent.putExtras(bundle);
    }
    return intent;
  }
}

So when I capture the image and then when the user is taken to edit the application, it doesn't, it takes me back to Home page again after capturing the image

Error log is:

2018-11-04 14:56:40.629 20408-21385/com.saashtechs.photoeditor  bitmap.size: 5184x3880
2018-11-04 14:56:40.629 20408-21385/com.saashtechs.photoeditor  resize(15)
2018-11-04 14:56:40.629 20408-21385/com.saashtechs.photoeditor  bitmap MP: 20, max MP: 15
2018-11-04 14:56:40.629 20408-21385/com.saashtechs.photoeditor  Image must be resized! 20MP -> 15MP
2018-11-04 14:56:40.629 20408-21385/com.saashtechs.photoeditor  target: 15MP = (4477x3351), max size: 4477
2018-11-04 14:56:40.629 20408-21385/com.saashtechs.photoeditor  original: 20MP = (5184x3880)
2018-11-04 14:56:40.629 20408-21385/com.saashtechs.photoeditor  maxWidth: 4477, maxHeight: 3351

Can you please tell me where am I going wrong ?

Thanks in advance

1

There are 1 answers

5
Sush On BEST ANSWER
if (extras != null) {
  Uri imageUri = Uri.parse(getIntent().getExtras().getString(IMAGE_URI));
  Intent imageEditorIntent = new AdobeImageIntent.Builder(this).setData(imageUri).build();
  startActivityForResult(imageEditorIntent, IMAGE_EDITOR_RESULT);
 // below line of code is not possible. your trying to receive result over 
  //here.  
 // . but your finishing it before it receives result
finish(); 
}

use below method close activity once data received. Pass data with set result method and then close. so your activity will have edited data.
better solution - you dont need this intermediate activity.

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
  switch (requestCode) {
    case IMAGE_EDITOR_RESULT:
      Uri editedImageUri = data.getParcelableExtra(AdobeImageIntent.EXTRA_OUTPUT_URI);
      Log.d(TAG, "editedImageUri: " + editedImageUri.toString());
      Bundle extra = data.getExtras();
      if (extra != null) {
        boolean changed = extra.getBoolean(AdobeImageIntent.EXTRA_OUT_BITMAP_CHANGED);
        Log.d(TAG, "Image edited: " + changed);
        if (changed) {
          mEditedImageView.setImageURI(editedImageUri);
        }
      }
      break;

    default:
      throw new IllegalArgumentException("Unexpected request code");
  }
}
}

As guidance -- below code is very bad practise in android

public static Intent getIntent(Context context, Bundle bundle) {
Intent intent = new Intent(context, MainActivity.class);
if (bundle != null) {
  intent.putExtras(bundle);
}
return intent;
}

Good practise.

private void navigateToPhotoEditActivity(Context context, Bundle bundle) 
       {
    Intent intent = new Intent(context, MainActivity.class);
    if (bundle != null) {
      intent.putExtras(bundle);
    }
     startActivity(intent);
    }