Return-Path: X-Original-To: apmail-cordova-issues-archive@minotaur.apache.org Delivered-To: apmail-cordova-issues-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 5055010029 for ; Wed, 16 Oct 2013 12:15:43 +0000 (UTC) Received: (qmail 37431 invoked by uid 500); 16 Oct 2013 12:15:43 -0000 Delivered-To: apmail-cordova-issues-archive@cordova.apache.org Received: (qmail 37409 invoked by uid 500); 16 Oct 2013 12:15:42 -0000 Mailing-List: contact issues-help@cordova.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cordova.apache.org Delivered-To: mailing list issues@cordova.apache.org Received: (qmail 37398 invoked by uid 99); 16 Oct 2013 12:15:42 -0000 Received: from arcas.apache.org (HELO arcas.apache.org) (140.211.11.28) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 16 Oct 2013 12:15:42 +0000 Date: Wed, 16 Oct 2013 12:15:41 +0000 (UTC) From: "Jonathan Naguin (JIRA)" To: issues@cordova.apache.org Message-ID: In-Reply-To: References: Subject: [jira] [Updated] (CB-5102) Memory leaks when resizing the photo on WP8 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 [ https://issues.apache.org/jira/browse/CB-5102?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Jonathan Naguin updated CB-5102: -------------------------------- Component/s: Plugin Camera > Memory leaks when resizing the photo on WP8 > ------------------------------------------- > > Key: CB-5102 > URL: https://issues.apache.org/jira/browse/CB-5102 > Project: Apache Cordova > Issue Type: Bug > Components: Plugin Camera, WP7, WP8 > Affects Versions: 3.1.0 > Environment: Nokia Lumia 925 running WP8 > Reporter: Jonathan Naguin > Assignee: Jesse MacFadyen > Priority: Critical > Labels: camera, memory-leak, wp7, wp8 > > I was testing the Camera on WP8 and I found memory problems using this code several times (5 to 10): > {code} > var _options = { > quality: 50, > destinationType: Camera.DestinationType.DATA_URL, > sourceType: Camera.PictureSourceType.CAMERA, > allowEdit: false, > encodingType: Camera.EncodingType.PNG, > saveToPhotoAlbum: false, > correctOrientation: true, > targetWidth: 1024, > targetHeight: 768 > }; > navigator.camera.getPicture(cameraSuccess, cameraError, _options); > {code} > I realized the problem is on "GetImageContent" and "ResizePhoto". It contains several problems disposing Streams and Bitmaps. > This is my re-implementation, which I tested and it works fine so far: > {code} > /// > /// Returns image content in a form of base64 string > /// > /// Image stream > /// Base64 representation of the image > private string GetImageContent(Stream stream) > { > byte[] imageContent = null; > try > { > //use photo's actual width & height if user doesn't provide width & height > if (cameraOptions.TargetWidth < 0 && cameraOptions.TargetHeight < 0) > { > int streamLength = (int)stream.Length; > imageContent = new byte[streamLength + 1]; > stream.Read(imageContent, 0, streamLength); > } > else > { > // resize photo > imageContent = ResizePhoto(stream); > } > } > finally > { > stream.Dispose(); > } > return Convert.ToBase64String(imageContent); > } > /// > /// Resize image > /// > /// Image stream > /// resized image > private byte[] ResizePhoto(Stream stream) > { > //output > byte[] resizedFile; > BitmapImage objBitmap = new BitmapImage(); > objBitmap.SetSource(stream); > objBitmap.CreateOptions = BitmapCreateOptions.None; > WriteableBitmap objWB = new WriteableBitmap(objBitmap); > objBitmap.UriSource = null; > //Keep proportionally > double ratio = Math.Min((double)cameraOptions.TargetWidth / objWB.PixelWidth, (double)cameraOptions.TargetHeight / objWB.PixelHeight); > int width = Convert.ToInt32( ratio * objWB.PixelWidth ); > int height = Convert.ToInt32( ratio * objWB.PixelHeight ); > //Hold the result stream > using (MemoryStream objBitmapStreamResized = new MemoryStream()) > { > try > { > // resize the photo with user defined TargetWidth & TargetHeight > Extensions.SaveJpeg(objWB, objBitmapStreamResized, width, height, 0, cameraOptions.Quality); > } > finally > { > //Dispose bitmaps immediately, they are memory expensive > DisposeImage(objBitmap); > DisposeImage(objWB); > GC.Collect(); > } > //Convert the resized stream to a byte array. > int streamLength = (int)objBitmapStreamResized.Length; > resizedFile = new Byte[streamLength]; //-1 > objBitmapStreamResized.Position = 0; > //for some reason we have to set Position to zero, but we don't have to earlier when we get the bytes from the chosen photo... > objBitmapStreamResized.Read(resizedFile, 0, streamLength); > } > return resizedFile; > } > /// > /// Util: Dispose a bitmap resource > /// > /// BitmapSource subclass to dispose > private void DisposeImage(BitmapSource image) > { > if (image != null) > { > try > { > using (var ms = new MemoryStream(new byte[] { 0x0 })) > { > image.SetSource(ms); > } > } > catch (Exception) > { > } > } > } > {code} > NOTE: > - It contains a solution for: https://issues.apache.org/jira/browse/CB-2737 -- This message was sent by Atlassian JIRA (v6.1#6144)