I'm using MemoryStream to get JPEGBuffer and then decoding that to Bitmap using JpegBitmapDecoder. This is causing the memory usage to increase every time I start reading the Live Video from Nikon Camera.
DispatchTimer tick method is written below (Runs 30 times every second):
private void dispatcherTimer_Tick(object sender, EventArgs e) {
if (isLiveVideoEnabled) {
try {
Nikon.NikonLiveViewImage liveImageFromCamera = ((MainWindow) myParent).currentDevice.GetLiveViewImage();
using(var liveImageStream = new MemoryStream(liveImageFromCamera.JpegBuffer))
{
liveImageComponent.Source = BitmapFrame.Create(liveImageStream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
liveLoop.Set();
}
} catch (Nikon.NikonException ex) {
MessageBox.Show(ex.Message);
}
}
}
This is the Code when user presses Capture Button. I'm stopping the Live View and then capturing the Photo from Nikon.
ImageBehavior.AddAnimationCompletedHandler(imageControl, async (sender , e) => {
// Disabling Live Stream
await liveLoop.WaitAsync();
isLiveVideoEnabled = false;
(myParent as MainWindow).currentDevice.LiveViewEnabled = false;
//Starting to Capture Photo
await (myParent as MainWindow).capturePhoto();
await (myParent as MainWindow).waitForTheImage();
string path = (myParent as MainWindow).getPhotoPath();
Console.WriteLine("******************** " + path + " *********************");
System.Windows.Media.Imaging.BitmapImage bImage = new BitmapImage(new Uri(path));
ImageBehavior.SetAnimatedSource(imageControl, null);
(sender as Image).Source = bImage;
Photos.imageDictionary[imageNumber] = path;
//Enabling the Live Stream
isLiveVideoEnabled = true;
currentImageControl = imageControl;
stopLoading();
showRetry();
(myParent as MainWindow).currentDevice.LiveViewEnabled = true;
});
This Application is in Continuous Operation.
- Touch Screen to Capture Photos
- Live view starts, user clicks on GIF which is counter
- As soon as GIF animation cycle is complete it stops the live view, and captures photo.
- User move to feedback section and one Cycle of operation completes here.
When I start my Application it starts with initial Memory 67MB.
First Cycle of Operation increases the memory to 185MB, and almost 130MB is added every time Live View Page is started.
First i thought the problem is regarding the WPF Pages but I closely checked Memory Usage, It increases only when we start live camera. Switching on pages doesn't increase any memory.
I think I'm using the wrong approach for MemoryStream. Please guide.
UPDATE 1 [ dispatcherTimer_Tick code is updated ]:
I implemented Clemens solution by introducing using(MemoryStream) inside the dispatcherTimer_Tick method. And Also froze the BitmapImage after BitmapImage.EndInit() But memory consumption is same and had no difference.
I started Profiler in VS and gathered the following information, At least Now I'm looking at the things which i should take care of.
Initial Image where i saw the byte[] stream is still connected and is not collected by GC.
After that I started looking further to get where it leads. Here is another image. (GetLiveViewImage is from nikoncswrapper)
And the last image which shows the Function Name:
Now i think i have more information to get to the problem. But I'm unable to understand what more i can do.
I even created a new Method to getBitmapImage:
public BitmapImage getBitmapFromURI(Uri uri) {
var image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = uri;
image.EndInit();
image.Freeze();
System.GC.Collect();
GC.WaitForPendingFinalizers();
return image;
}


