[ https://issues.apache.org/jira/browse/CB-5102?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Jesse MacFadyen updated CB-5102: -------------------------------- Fix Version/s: (was: 3.3.0) 3.4.0 > 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 > Fix For: 3.4.0 > > > 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} > /// <summary> > /// Returns image content in a form of base64 string > /// </summary> > /// <param name="stream">Image stream</param> > /// <returns>Base64 representation of the image</returns> > 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); > } > /// <summary> > /// Resize image > /// </summary> > /// <param name="stream">Image stream</param> > /// <returns>resized image</returns> > 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; > } > /// <summary> > /// Util: Dispose a bitmap resource > /// </summary> > /// <param name="image">BitmapSource subclass to dispose</param> > 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.5#6160)