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;
}