mirror of
https://gitee.com/shuto/cordova-imagePicker.git
synced 2026-05-23 00:05:03 +08:00
Merge pull request #23 from wymsee/android_oom
Out of memory exception on rotate of images
This commit is contained in:
@@ -483,6 +483,8 @@ public class MultiImageChooserActivity extends Activity implements OnItemClickLi
|
||||
|
||||
|
||||
private class ResizeImagesTask extends AsyncTask<Set<Entry<String, Integer>>, Void, ArrayList<String>> {
|
||||
private Exception asyncTaskError = null;
|
||||
|
||||
@Override
|
||||
protected ArrayList<String> doInBackground(Set<Entry<String, Integer>>... fileSets) {
|
||||
Set<Entry<String, Integer>> fileNames = fileSets[0];
|
||||
@@ -493,6 +495,7 @@ public class MultiImageChooserActivity extends Activity implements OnItemClickLi
|
||||
while(i.hasNext()) {
|
||||
Entry<String, Integer> imageInfo = i.next();
|
||||
File file = new File(imageInfo.getKey());
|
||||
int rotate = imageInfo.getValue().intValue();
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inSampleSize = 1;
|
||||
options.inJustDecodeBounds = true;
|
||||
@@ -506,41 +509,43 @@ public class MultiImageChooserActivity extends Activity implements OnItemClickLi
|
||||
int inSampleSize = calculateInSampleSize(options, finalWidth, finalHeight);
|
||||
options = new BitmapFactory.Options();
|
||||
options.inSampleSize = inSampleSize;
|
||||
bmp = BitmapFactory.decodeFile(file.getAbsolutePath(), options);
|
||||
if (bmp == null) {
|
||||
throw new IOException("The image file could not be opened.");
|
||||
try {
|
||||
bmp = this.tryToGetBitmap(file, options, rotate, true);
|
||||
} catch (OutOfMemoryError e) {
|
||||
options.inSampleSize = calculateNextSampleSize(options.inSampleSize);
|
||||
try {
|
||||
bmp = this.tryToGetBitmap(file, options, rotate, false);
|
||||
} catch (OutOfMemoryError e2) {
|
||||
throw new IOException("Unable to load image into memory.");
|
||||
}
|
||||
}
|
||||
scale = calculateScale(options.outWidth, options.outHeight);
|
||||
bmp = this.getResizedBitmap(bmp, scale);
|
||||
} else {
|
||||
try {
|
||||
bmp = BitmapFactory.decodeFile(file.getAbsolutePath());
|
||||
bmp = this.tryToGetBitmap(file, null, rotate, false);
|
||||
} catch(OutOfMemoryError e) {
|
||||
options = new BitmapFactory.Options();
|
||||
options.inSampleSize = 2;
|
||||
try {
|
||||
bmp = BitmapFactory.decodeFile(file.getAbsolutePath(), options);
|
||||
bmp = this.tryToGetBitmap(file, options, rotate, false);
|
||||
} catch(OutOfMemoryError e2) {
|
||||
options = new BitmapFactory.Options();
|
||||
options.inSampleSize = 4;
|
||||
bmp = BitmapFactory.decodeFile(file.getAbsolutePath(), options);
|
||||
try {
|
||||
bmp = this.tryToGetBitmap(file, options, rotate, false);
|
||||
} catch (OutOfMemoryError e3) {
|
||||
throw new IOException("Unable to load image into memory.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int rotate = imageInfo.getValue().intValue();
|
||||
if (rotate != 0) {
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.setRotate(rotate);
|
||||
bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
|
||||
}
|
||||
|
||||
|
||||
file = this.storeImage(bmp, file.getName());
|
||||
al.add(Uri.fromFile(file).toString());
|
||||
}
|
||||
return al;
|
||||
} catch(IOException e) {
|
||||
try {
|
||||
asyncTaskError = e;
|
||||
for (int i = 0; i < al.size(); i++) {
|
||||
URI uri = new URI(al.get(i));
|
||||
File file = new File(uri);
|
||||
@@ -557,22 +562,49 @@ public class MultiImageChooserActivity extends Activity implements OnItemClickLi
|
||||
@Override
|
||||
protected void onPostExecute(ArrayList<String> al) {
|
||||
Intent data = new Intent();
|
||||
|
||||
if (al.size() > 0) {
|
||||
|
||||
if (asyncTaskError != null) {
|
||||
Bundle res = new Bundle();
|
||||
res.putString("ERRORMESSAGE", asyncTaskError.getMessage());
|
||||
data.putExtras(res);
|
||||
setResult(RESULT_CANCELED, data);
|
||||
} else if (al.size() > 0) {
|
||||
Bundle res = new Bundle();
|
||||
res.putStringArrayList("MULTIPLEFILENAMES", al);
|
||||
if (imagecursor != null) {
|
||||
res.putInt("TOTALFILES", imagecursor.getCount());
|
||||
}
|
||||
|
||||
data.putExtras(res);
|
||||
setResult(RESULT_OK, data);
|
||||
} else {
|
||||
setResult(RESULT_CANCELED, data);
|
||||
}
|
||||
|
||||
progress.dismiss();
|
||||
finish();
|
||||
}
|
||||
|
||||
private Bitmap tryToGetBitmap(File file, BitmapFactory.Options options, int rotate, boolean shouldScale) throws IOException, OutOfMemoryError {
|
||||
Bitmap bmp;
|
||||
if (options == null) {
|
||||
bmp = BitmapFactory.decodeFile(file.getAbsolutePath());
|
||||
} else {
|
||||
bmp = BitmapFactory.decodeFile(file.getAbsolutePath(), options);
|
||||
}
|
||||
if (bmp == null) {
|
||||
throw new IOException("The image file could not be opened.");
|
||||
}
|
||||
if (options != null && shouldScale) {
|
||||
float scale = calculateScale(options.outWidth, options.outHeight);
|
||||
bmp = this.getResizedBitmap(bmp, scale);
|
||||
}
|
||||
if (rotate != 0) {
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.setRotate(rotate);
|
||||
bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
|
||||
}
|
||||
return bmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following functions are originally from
|
||||
@@ -631,6 +663,11 @@ public class MultiImageChooserActivity extends Activity implements OnItemClickLi
|
||||
|
||||
return inSampleSize;
|
||||
}
|
||||
|
||||
private int calculateNextSampleSize(int sampleSize) {
|
||||
double logBaseTwo = (int)(Math.log(sampleSize) / Math.log(2));
|
||||
return (int)Math.pow(logBaseTwo + 1, 2);
|
||||
}
|
||||
|
||||
private float calculateScale(int width, int height) {
|
||||
float widthScale = 1.0f;
|
||||
|
||||
@@ -17,53 +17,56 @@ import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
public class ImagePicker extends CordovaPlugin {
|
||||
public static String TAG = "ImagePicker";
|
||||
|
||||
private CallbackContext callbackContext;
|
||||
private JSONObject params;
|
||||
|
||||
public static String TAG = "ImagePicker";
|
||||
|
||||
private CallbackContext callbackContext;
|
||||
private JSONObject params;
|
||||
|
||||
public boolean execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException {
|
||||
this.callbackContext = callbackContext;
|
||||
this.params = args.getJSONObject(0);
|
||||
this.callbackContext = callbackContext;
|
||||
this.params = args.getJSONObject(0);
|
||||
if (action.equals("getPictures")) {
|
||||
Intent intent = new Intent(cordova.getActivity(), MultiImageChooserActivity.class);
|
||||
int max = 20;
|
||||
int desiredWidth = 0;
|
||||
int desiredHeight = 0;
|
||||
int quality = 100;
|
||||
int desiredHeight = 0;
|
||||
int quality = 100;
|
||||
if (this.params.has("maximumImagesCount")) {
|
||||
max = this.params.getInt("maximumImagesCount");
|
||||
max = this.params.getInt("maximumImagesCount");
|
||||
}
|
||||
if (this.params.has("width")) {
|
||||
desiredWidth = this.params.getInt("width");
|
||||
desiredWidth = this.params.getInt("width");
|
||||
}
|
||||
if (this.params.has("height")) {
|
||||
desiredWidth = this.params.getInt("height");
|
||||
desiredWidth = this.params.getInt("height");
|
||||
}
|
||||
if (this.params.has("quality")) {
|
||||
quality = this.params.getInt("quality");
|
||||
}
|
||||
quality = this.params.getInt("quality");
|
||||
}
|
||||
intent.putExtra("MAX_IMAGES", max);
|
||||
intent.putExtra("WIDTH", desiredWidth);
|
||||
intent.putExtra("HEIGHT", desiredHeight);
|
||||
intent.putExtra("QUALITY", quality);
|
||||
if (this.cordova != null) {
|
||||
this.cordova.startActivityForResult((CordovaPlugin) this, intent, 0);
|
||||
}
|
||||
if (this.cordova != null) {
|
||||
this.cordova.startActivityForResult((CordovaPlugin) this, intent, 0);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||
ArrayList<String> fileNames = data.getStringArrayListExtra("MULTIPLEFILENAMES");
|
||||
JSONArray res = new JSONArray(fileNames);
|
||||
this.callbackContext.success(res);
|
||||
} else if (resultCode == Activity.RESULT_CANCELED) {
|
||||
JSONArray res = new JSONArray();
|
||||
this.callbackContext.success(res);
|
||||
} else {
|
||||
this.callbackContext.error("No images selected");
|
||||
}
|
||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||
ArrayList<String> fileNames = data.getStringArrayListExtra("MULTIPLEFILENAMES");
|
||||
JSONArray res = new JSONArray(fileNames);
|
||||
this.callbackContext.success(res);
|
||||
} else if (resultCode == Activity.RESULT_CANCELED && data != null) {
|
||||
String error = data.getStringExtra("ERRORMESSAGE");
|
||||
this.callbackContext.error(error);
|
||||
} else if (resultCode == Activity.RESULT_CANCELED) {
|
||||
JSONArray res = new JSONArray();
|
||||
this.callbackContext.success(res);
|
||||
} else {
|
||||
this.callbackContext.error("No images selected");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user