CameraLauncher Plugin enhancement for loading big image files to avoid 
OutOfMemory exceptions
---------------------------------------------------------------------------------------------

                 Key: CB-14
                 URL: https://issues.apache.org/jira/browse/CB-14
             Project: Apache Callback
          Issue Type: Improvement
          Components: Android
    Affects Versions: 1.1.0
         Environment: Android SDK: 2.x & above
JDK: 1.6
Eclipse: Helios
            Reporter: Bright Zheng
            Priority: Critical
             Fix For: 2.0.0


Currently the CameraLauncher plugin of Phonegap (or Apache Callback) is using 
Android default API for stream decoding.
It will be very easy to get crash by throwing out the OutOfMemory exceptions 
while loading bigger image files.

So I add a new method called safeDecodeStream for better stream decoding.
{code:title=safeDecodeStream method|borderStyle=solid}

    /**
     * A safer decodeStream method
     * rather than the one of {@link BitmapFactory}
     * which will be easy to get OutOfMemory Exception
     * while loading a big image file.
     * 
     * @param uri
     * @param width
     * @param height
     * @return
     * @throws FileNotFoundException
     */
    protected Bitmap safeDecodeStream(Uri uri, int width, int height)
    throws FileNotFoundException{
                int scale = 1;
                BitmapFactory.Options options = new BitmapFactory.Options();
                android.content.ContentResolver resolver = 
this.ctx.getContentResolver();
                
                if(width>0 || height>0){
                        // Decode image size without loading all data into 
memory
                        options.inJustDecodeBounds = true;
                        BitmapFactory.decodeStream(
                                        new 
BufferedInputStream(resolver.openInputStream(uri), 16*1024),
                                        null,
                                        options);
                        
                        int w = options.outWidth;
                        int h = options.outHeight;
                        while (true) {
                                if ((width>0 && w/2 < width)
                                                || (height>0 && h/2 < height)){
                                        break;
                                }
                                w /= 2;
                                h /= 2;
                                scale *= 2;
                        }
                }

                // Decode with inSampleSize option
                options.inJustDecodeBounds = false;
                options.inSampleSize = scale;
                return BitmapFactory.decodeStream(
                                new 
BufferedInputStream(resolver.openInputStream(uri), 16*1024), 
                                null, 
                                options);
        }  
{code} 

And then change all the codes which are invoking the Android decodeStream API 
directly to this method.
e.g.
{code:title=usage example|borderStyle=solid}

//Updated by Bright for safer decodeStream
//android.content.ContentResolver resolver = this.ctx.getContentResolver();
//bitmap = 
android.graphics.BitmapFactory.decodeStream(resolver.openInputStream(uri));
bitmap = safeDecodeStream(uri, this.targetWidth, this.targetHeight);

{code} 



--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: 
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to