This is an automated email from the ASF dual-hosted git repository.

GitToTheHub pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cordova-plugin-camera.git


The following commit(s) were added to refs/heads/master by this push:
     new dd39592  fix(android): Prevent out of memory errors on Android when 
selecting large media (video) files from the gallery picker. (#923)
dd39592 is described below

commit dd39592faf6ab0232d15aba6b91ec527949229d7
Author: AL <[email protected]>
AuthorDate: Mon Apr 20 17:19:26 2026 +0100

    fix(android): Prevent out of memory errors on Android when selecting large 
media (video) files from the gallery picker. (#923)
    
    Changes from #906 resulted in all gallery picker results being read in full 
into a byte array. This works fine when dealing with images, however when 
larger files (videos for example) are selected it will nearly always result in 
an out of memory error (reading too much data in one go). With videos no 
transformation is required, the URI simply need to be returned.
    
    Co-authored-by: Alister Stevens <[email protected]>
---
 src/android/CameraLauncher.java | 143 +++++++++++++++-------------------------
 1 file changed, 54 insertions(+), 89 deletions(-)

diff --git a/src/android/CameraLauncher.java b/src/android/CameraLauncher.java
index 94e482a..af03a9c 100644
--- a/src/android/CameraLauncher.java
+++ b/src/android/CameraLauncher.java
@@ -749,6 +749,23 @@ public class CameraLauncher extends CordovaPlugin 
implements MediaScannerConnect
 
         String uriString = uri.toString();
         String mimeTypeOfGalleryFile = FileHelper.getMimeType(uriString, 
this.cordova);
+
+        // If you ask for video or the selected file cannot be processed
+        // there will be no attempt to resize any returned data.
+        if (this.mediaType == VIDEO || 
!isImageMimeTypeProcessable(mimeTypeOfGalleryFile)) {
+            this.callbackContext.success(uriString);
+            return;
+        }
+
+        // This is a special case to just return the path as no scaling,
+        // rotating, nor compressing needs to be done
+        if (this.targetHeight == -1 && this.targetWidth == -1 &&
+                destType == FILE_URI && !this.correctOrientation &&
+                
getMimetypeForEncodingType().equalsIgnoreCase(mimeTypeOfGalleryFile)) {
+            this.callbackContext.success(uriString);
+            return;
+        }
+
         InputStream input;
         try {
             input = 
cordova.getActivity().getContentResolver().openInputStream(uri);
@@ -764,105 +781,53 @@ public class CameraLauncher extends CordovaPlugin 
implements MediaScannerConnect
 
         try {
             byte[] data = readData(input);
+            Bitmap bitmap = null;
 
-            // If you ask for video or the selected file cannot be processed
-            // there will be no attempt to resize any returned data.
-            if (this.mediaType == VIDEO || 
!isImageMimeTypeProcessable(mimeTypeOfGalleryFile)) {
-                this.callbackContext.success(uriString);
-            } else {
-                Bitmap bitmap = null;
+            try {
+                bitmap = getScaledAndRotatedBitmap(data, 
mimeTypeOfGalleryFile);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
 
-                // This is a special case to just return the path as no 
scaling,
-                // rotating, nor compressing needs to be done
-                if (this.targetHeight == -1 && this.targetWidth == -1 &&
-                    destType == FILE_URI && !this.correctOrientation &&
-                    
getMimetypeForEncodingType().equalsIgnoreCase(mimeTypeOfGalleryFile)) {
-                    this.callbackContext.success(uriString);
-                } else {
-                    try {
-                        bitmap = getScaledAndRotatedBitmap(data, 
mimeTypeOfGalleryFile);
-                    } catch (IOException e) {
-                        e.printStackTrace();
-                    }
-                    if (bitmap == null) {
-                        LOG.d(LOG_TAG, "I either have an unreadable uri or 
null bitmap");
-                        this.failPicture("Unable to create bitmap!");
-                        return;
-                    }
+            if (bitmap == null) {
+                LOG.d(LOG_TAG, "I either have an unreadable uri or null 
bitmap");
+                this.failPicture("Unable to create bitmap!");
+                return;
+            }
 
-                    // If sending base64 image back
-                    if (destType == DATA_URL) {
-                        this.processPicture(bitmap, this.encodingType);
-                    }
+            // If sending base64 image back
+            if (destType == DATA_URL) {
+                this.processPicture(bitmap, this.encodingType);
+            }
+            // If sending filename back
+            else if (destType == FILE_URI) {
+                // Did we modify the image?
+                if ((this.targetHeight > 0 && this.targetWidth > 0) ||
+                        (this.correctOrientation && this.orientationCorrected) 
||
+                        
!mimeTypeOfGalleryFile.equalsIgnoreCase(getMimetypeForEncodingType())) {
+                    try {
+                        String modifiedPath = 
this.outputModifiedBitmap(bitmap, uri, mimeTypeOfGalleryFile);
+                        // The modified image is cached by the app in order to 
get around this and not have to delete you
+                        // application cache I'm adding the current system 
time to the end of the file url.
+                        this.callbackContext.success("file://" + modifiedPath 
+ "?" + System.currentTimeMillis());
 
-                    // If sending filename back
-                    else if (destType == FILE_URI) {
-                        // Did we modify the image?
-                        if ((this.targetHeight > 0 && this.targetWidth > 0) ||
-                            (this.correctOrientation && 
this.orientationCorrected) ||
-                            
!mimeTypeOfGalleryFile.equalsIgnoreCase(getMimetypeForEncodingType())) {
-                            try {
-                                String modifiedPath = 
this.outputModifiedBitmap(bitmap, uri, mimeTypeOfGalleryFile);
-                                // The modified image is cached by the app in 
order to get around this and not have to delete you
-                                // application cache I'm adding the current 
system time to the end of the file url.
-                                this.callbackContext.success("file://" + 
modifiedPath + "?" + System.currentTimeMillis());
-
-                            } catch (Exception e) {
-                                e.printStackTrace();
-                                this.failPicture("Error retrieving image: " + 
e.getLocalizedMessage());
-                            }
-                        } else {
-                            this.callbackContext.success(uriString);
-                        }
-                    }
-                    if (bitmap != null) {
-                        bitmap.recycle();
-                        bitmap = null;
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                        this.failPicture("Error retrieving image: " + 
e.getLocalizedMessage());
                     }
-                    System.gc();
-                }
-                if (bitmap == null) {
-                    LOG.d(LOG_TAG, "I either have an unreadable uri or null 
bitmap");
-                    this.failPicture("Unable to create bitmap!");
-                    return;
-                }
-
-                // If sending base64 image back
-                if (destType == DATA_URL) {
-                    this.processPicture(bitmap, this.encodingType);
+                } else {
+                    this.callbackContext.success(uriString);
                 }
+            }
 
-                // If sending filename back
-                else if (destType == FILE_URI) {
-                    // Did we modify the image?
-                    if ( (this.targetHeight > 0 && this.targetWidth > 0) ||
-                            (this.correctOrientation && 
this.orientationCorrected) ||
-                            
!mimeTypeOfGalleryFile.equalsIgnoreCase(getMimetypeForEncodingType()))
-                    {
-                        try {
-                            String modifiedPath = 
this.outputModifiedBitmap(bitmap, uri, mimeTypeOfGalleryFile);
-                            // The modified image is cached by the app in 
order to get around this and not have to delete you
-                            // application cache I'm adding the current system 
time to the end of the file url.
-                            this.callbackContext.success("file://" + 
modifiedPath + "?" + System.currentTimeMillis());
-
-                        } catch (Exception e) {
-                            e.printStackTrace();
-                            this.failPicture("Error retrieving image: 
"+e.getLocalizedMessage());
-                        }
-                    } else {
-                        this.callbackContext.success(uriString);
-                    }
-                }
-                if (bitmap != null) {
-                    bitmap.recycle();
-                    bitmap = null;
-                }
-                System.gc();
+            if (bitmap != null) {
+                bitmap.recycle();
+                bitmap = null;
             }
 
+            System.gc();
             input.close();
-        }
-        catch (Exception e) {
+        }  catch (Exception e) {
             try {
                 input.close();
             } catch (IOException ex) {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to