Я использую MemoryStream
, чтобы получить JPEGBuffer, а затем декодирую его в Bitmap, используя JpegBitmapDecoder
.Это приводит к увеличению использования памяти каждый раз, когда я начинаю читать живое видео с камеры Nikon.
DispatchTimer
метод тиков написан ниже (запускается 30 раз каждую секунду):
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);
}
}
}
Это код, когда пользователь нажимает Capture Button
.Я прекращаю просмотр в режиме реального времени, а затем снимаю фотографию с 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;
});
Это приложение работает в непрерывном режиме.
- Сенсорный экран для захвата фотографий
- Запускается просмотр в реальном времени, пользователь нажимает на GIF, который является счетчиком
- Как только цикл анимации GIF завершается, он останавливает просмотр в реальном времени и захватывает фотографию.
- Пользователь переходит в раздел обратной связи, и здесь завершается один цикл операций.
Когда я запускаю свое приложение, оно запускается с начальной памятью 67MB
.Первый цикл работы увеличивает объем памяти до 185MB
, и почти каждый 130MB
добавляется при каждом запуске страницы просмотра в реальном времени.
Сначала я подумал, что проблема связана с WPF Pages
, но я внимательно проверил использование памяти, оно увеличивается только тогда, когда мы запускаем живую камеру.Переключение на страницы не увеличивает память.
Я думаю, что использую неправильный подход для MemoryStream
.Пожалуйста, руководство.
ОБНОВЛЕНИЕ 1 [dispatcherTimer_Tick
код обновлен]:
Я реализовал решение Клеменса, введя using(MemoryStream)
в методе dispatcherTimer_Tick
.А также заморозил BitmapImage
после BitmapImage.EndInit()
Но потребление памяти такое же и без разницы.
Я запустил Profiler в VS и собрал следующую информацию, по крайней мере, сейчас я смотрю на вещи, о которых я должен позаботиться.
Исходное изображение, где я видел, что byte[] stream
все еще подключено и не собрано GC.
После этого я началглядя дальше, чтобы добраться туда, куда это ведет.Вот другое изображение.(GetLiveViewImage
от nikoncswrapper
)
И последнее изображение с именем функции:
Теперь я думаю, что у меня есть больше информации, чтобы добраться до проблемы.Но я не могу понять, что еще я могу сделать.
Я даже создал новый метод для 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;
}