OutOfMemory

In some instances, the image returned by the camera may be too big for our application to load into memory outright. In order to rectify this situation, here is a method that you can use to resize an image on disk. Just pass in the path of the original and where you want to new image saved.

// Loads an image from disk at screen resolution and saves it back out at the same size.
void resizeImage(String imageFilePath, String newImageFilePath) {
  try {
    // Load up the image's dimensions not the image itself 
    android.graphics.BitmapFactory.Options bmpFactoryOptions = new android.graphics.BitmapFactory.Options(); 
    bmpFactoryOptions.inJustDecodeBounds = true; 
    android.graphics.Bitmap bmp = android.graphics.BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);
    int heightRatio = (int) Math.ceil(bmpFactoryOptions.outHeight / (float) height);
    int widthRatio = (int) Math.ceil(bmpFactoryOptions.outWidth / (float) width);
    println("HEIGHTRATIO: " + heightRatio); 
    println("WIDTHRATIO: " + widthRatio);
    // If both of the ratios are greater than 1, one of the sides of // the image is greater than the screen 
    if (heightRatio > 1 && widthRatio > 1) {
      if (heightRatio > widthRatio) { 
        // Height ratio is larger, scale according to it 
        bmpFactoryOptions.inSampleSize = heightRatio;
      } else { 
        // Width ratio is larger, scale according to it 
        bmpFactoryOptions.inSampleSize = widthRatio;
      }
    }
    // Decode it for real 
    bmpFactoryOptions.inJustDecodeBounds = false; 
    bmp = android.graphics.BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);
    
    java.io.File newImageFile = new java.io.File(newImageFilePath);
    android.net.Uri newImageUri = android.net.Uri.fromFile(newImageFile);
    OutputStream imageFileOS = getContentResolver().openOutputStream(newImageUri);
    bmp.compress(android.graphics.Bitmap.CompressFormat.JPEG, 90, imageFileOS);
    
    println("Resized image, wrote out to: " + newImageFile.getAbsolutePath());
    
  } catch (Exception e) {
    println(e.toString());
    e.printStackTrace(); 
  }
}

For instance, if I had a camera image on the SD card called dottie.jpg and I wanted make it smaller I would do the following:

PImage theImage;

void setup() {  
  // If the image is too big, you need to make it smaller before you can load it.
 resizeImage(android.os.Environment.getExternalStorageDirectory().getAbsolutePath() + "/dottie.jpg", android.os.Environment.getExternalStorageDirectory().getAbsolutePath() + "/dottie_small.jpg");
  theImage = loadImage(android.os.Environment.getExternalStorageDirectory().getAbsolutePath() + "/dottie_small.jpg");
}