Search code examples
androidandroid-cameraadobecreativesdkphotoeditorsdk

'Image must be resized' error when the image is captured from phone when the camera size is more than 15Megapixel


Hi Stack Overflow team,

Following is the java code of PhotoEditor Android app for capturing image and saving the image in the phone

Following is the MainActivity.java file:

package com.example.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(); // Comment this out to receive edited image
    }
  }

  // Do something with the edited image
  @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;
  }
}

Following is the HomeActivity.java file:

package com.example.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.File;
import java.io.IOException;
import java.text.DateFormat;
import java.util.Date;
import java.util.Objects;

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.example.photoeditor";
  private static final int CAMERA_PERMISSION_REQ_CODE = 1001;
  private static final int STORAGE_PERMISSION_REQ_CODE = 1002;
  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());
        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();
    return image;
  }

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

  @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);
        Uri imageUri = Uri.fromFile(imageFile);
        startActivity(MainActivity.getIntent(this, uriToBundle(imageUri)));
      }
    } 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 activity_home XML file:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.photoeditor.HomeActivity">

  <ImageView
      android:id="@+id/home_background"
      android:layout_width="250dp"
      android:layout_height="250dp"
      android:layout_centerInParent="true"
      android:contentDescription="@string/astronaut_content_desc"
      android:scaleType="centerCrop"
      android:src="@drawable/picture"/>

  <LinearLayout
      android:id="@+id/title_home"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_centerHorizontal="true"
      android:layout_marginTop="75dp"
      android:gravity="center"
      tools:ignore="UseCompoundDrawables">

    <ImageView
        android:id="@+id/home_logo"
        android:layout_width="@dimen/logo_width"
        android:layout_height="@dimen/logo_height"
        android:contentDescription="@string/app_logo_content_desc"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/app_name"
        android:textColor="@color/whitePrimary"
        android:textSize="50sp"/>
  </LinearLayout>

  <LinearLayout
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentBottom="true"
      android:layout_below="@id/title_home"
      android:layout_centerHorizontal="true"
      android:layout_marginBottom="25dp"
      android:gravity="bottom">

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="65dp">

      <ImageView
          android:id="@+id/camera_button_image"
          android:layout_width="40dp"
          android:layout_height="40dp"
          android:layout_centerHorizontal="true"
          android:contentDescription="@string/camera_button_content_desc"
          android:onClick="openCamera"
          android:src="@drawable/ic_camera_alt_white"/>

      <TextView
          android:id="@+id/camera_button_text"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_below="@id/camera_button_image"
          android:layout_marginTop="7dp"
          android:onClick="openCamera"
          android:text="@string/camera_button_text"
          android:textColor="@color/whitePrimary"/>
    </RelativeLayout>

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

      <ImageView
          android:id="@+id/gallery_button_image"
          android:layout_width="40dp"
          android:layout_height="40dp"
          android:layout_centerHorizontal="true"
          android:contentDescription="@string/gallery_button_content_desc"
          android:onClick="openGallery"
          android:src="@drawable/ic_phone_android_white"/>

      <TextView
          android:id="@+id/gallery_button_text"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_below="@id/gallery_button_image"
          android:layout_marginTop="7dp"
          android:onClick="openGallery"
          android:text="@string/gallery_button_text"
          android:textColor="@color/whitePrimary"/>
    </RelativeLayout>

  </LinearLayout>

</RelativeLayout>

Following is the activity_main XML file:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorPrimary"
    tools:context="com.example.photoeditor.MainActivity">

  <ImageView
      android:id="@+id/edited_image_view"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:adjustViewBounds="true"
      android:contentDescription="@string/edited_image_content_desc"/>

</LinearLayout>

Issue is after capturing the image and then after editing the photo from the app and then when the image has to be saved, I see that image is not getting saved in the phone

When I see the Logcat in Android Studio, I saw this warning:

2018-10-27 23:59:57.250 2437-3574/com.example.photoeditor D/skia-encoders: [time] JPEG Decode 951
2018-10-27 23:59:57.250 2437-3574/com.example.photoeditor V/moahd-jni: decode time: 952
2018-10-27 23:59:57.250 2437-3574/com.example.photoeditor V/moahd-jni: bitmap.size: 5184x3880
2018-10-27 23:59:57.250 2437-3574/com.example.photoeditor I/moahd-jni: resize(15)
2018-10-27 23:59:57.250 2437-3574/com.example.photoeditor V/moahd-jni: bitmap MP: 20, max MP: 15
2018-10-27 23:59:57.250 2437-3574/com.example.photoeditor W/moahd-jni: Image must be resized! 20MP -> 15MP
2018-10-27 23:59:57.250 2437-3574/com.example.photoeditor V/moahd-jni: target: 15MP = (4477x3351), max size: 4477
2018-10-27 23:59:57.250 2437-3574/com.example.photoeditor V/moahd-jni: original: 20MP = (5184x3880)
2018-10-27 23:59:57.250 2437-3574/com.example.photoeditor V/moahd-jni: maxWidth: 4477, maxHeight: 3351

So saving issue is only if the image is captured when the camera size of the phone is more than 15Megapixel.

Can anyone please help with the possible code solution?

Thanks in advance


Solution

  • Use this code to resize and save:

    Bitmap image = (Bitmap) "your image";
    image = Bitmap.createScaledBitmap(photo, 100, 100, false);
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    image.compress(Bitmap.CompressFormat.JPEG, 60, bytes);
    
    File file = new File(Environment.getExternalStorageDirectory()
            + File.separator + "name.jpg");
    file.createNewFile();
    FileOutputStream fo = new FileOutputStream(file);
    fo.write(bytes.toByteArray());
    fo.close();
    

    60 indicates the quality of compression: 0 is maximum compression low quality. 100 is least compression highest quality