CommunityToolkit / CommunityToolkit/Windows
Memory Management with `ImageCropper` Control
- Lingua principale
- C#
- Stelle
- 1.1k
- Fork
- 166
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Descrizione
### Describe the bug
When using the `ImageCropper` control in the Windows Community Toolkit Gallery, I have observed the following memory-related issues:
1. **Memory Consumption**: When selecting a high-resolution image (dimensions: 8000 x 8000), the memory usage increases significantly. This is expected, but a concern arises when selecting additional images or re-selecting the same image. Each new image selection causes a cumulative increase in memory usage, indicating that the previous images are not being properly disposed of.
2. **Memory Usage Table**:
- After 1st image selection:

- After 2nd image selection:

- After 3rd image selection:

- After 4th image selection:

3. **Behavior**: The issue escalates when attempting to find a way to dispose of objects in a WinUI 3 app. After selecting high-resolution images multiple times (with memory usage exceeding 1000 MB), the application stops running unexpectedly without any error or exception. I have not been able to identify a method to release the memory effectively after selecting a new image.
```xaml
```
```csharp
using CommunityToolkit.WinUI.Controls;
using Microsoft.UI.Xaml;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.Storage.Pickers;
using Windows.Storage;
namespace MyApp
{
public sealed partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
}
private async Task PickImage()
{
var openPicker = new FileOpenPicker();
var window = this;
var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(window);
WinRT.Interop.InitializeWithWindow.Initialize(openPicker, hWnd);
openPicker.ViewMode = PickerViewMode.Thumbnail;
openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
openPicker.FileTypeFilter.Add(".jpg");
openPicker.FileTypeFilter.Add(".jpeg");
openPicker.FileTypeFilter.Add(".png");
var file = await openPicker.PickSingleFileAsync();
if (file != null && imageCropper != null)
{
await imageCropper.LoadImageFromFile(file);
}
}
private async Task SaveCroppedImage()
{
var savePicker = new FileSavePicker
{
SuggestedStartLocation = PickerLocationId.PicturesLibrary,
SuggestedFileName = "Cropped_Image",
FileTypeChoices =
{
{ "PNG Picture", new List { ".png" } },
{ "JPEG Picture", new List { ".jpg" } }
}
};
var imageFile = await savePicker.PickSaveFileAsync();
if (imageFile != null)
{
BitmapFileFormat bitmapFileFormat;
switch (imageFile.FileType.ToLower())
{
case ".png":
bitmapFileFormat = BitmapFileFormat.Png;
break;
case ".jpg":
bitmapFileFormat = BitmapFileFormat.Jpeg;
break;
default:
bitmapFileFormat = BitmapFileFormat.Png;
break;
}
using (var fileStream = await imageFile.OpenAsync(FileAccessMode.ReadWrite, StorageOpenOptions.None))
{
await imageCropper.SaveAsync(fileStream, bitmapFileFormat);
}
}
}
private async void PickButton_Click(object sender, RoutedEventArgs e)
{
await PickImage();
}
private async void SaveButton_Click(object sender, RoutedEventArgs e)
{
await SaveCroppedImage();
}
private void ResetButton_Click(object sender, RoutedEventArgs e)
{
imageCropper.Reset();
}
}
}
```
### Steps to reproduce
***I. Steps to Reproduce the Memory Management Issue in WCT Gallery:***
1. **Run the Application**:
- Launch your application to display the `MainWindow` with the `ImageCropper` control and the "Pick image" button.
2. **Select a High-Resolution Image**:
- Click the "Pick image" button to open the file picker.
- Choose a high-resolution image (e.g., 8000 x 8000 pixels) from your file system ([this is the image I used](https://399d-23h-59m-59s.com/press/images/Longing_shade_pics_4.png)).
3. **Observe Memory Usage**:
- Use Task Manager or a memory profiling tool to monitor the application's memory usage.
4. **Re-select the Same High-Resolution Image**:
- Click the "Pick image" button again and select the same high-resolution image you picked earlier.
- Observe the increase in memory usage.
5. **Repeat the Image Selection**:
- Continue clicking the "Pick image" button and re-selecting the same high-resolution image multiple times.
- Track the cumulative increase in memory usage with each image selection.
***II. Steps to Reproduce the Memory Management Issue in WinUI3:***
1. **Setup the Application**:
- Use the provided XAML and C# code to set up your WinUI 3 project.
2. **Run the Application**:
- Launch the application to display `MainWindow` with the `ImageCropper` control and the "Pick image" button.
3. **Select a High-Resolution Image**:
- Click the "Pick image" button.
- Choose a high-resolution image (e.g., 8000 x 8000 pixels) from your file system.
4. **Observe Memory Usage**:
- Monitor the application’s memory usage using Task Manager or a similar profiling tool.
5. **Re-select the Same Image**:
- Click the "Pick image" button again and select the same high-resolution image you picked earlier.
- Observe the increase in memory usage.
6. **Repeat the Process**:
- Continue clicking the "Pick image" button and re-selecting the same high-resolution image multiple times.
- Monitor the cumulative increase in memory usage with each selection.
7. **Check Application Behavior**:
- Continue the process until you notice a significant increase in memory usage or if the application stops running without errors (e.g., after memory usage exceeds 1000 MB).
### Expected behavior
- Memory usage should not increase cumulatively with each selection of the same image. The previously selected image should be properly disposed of to prevent memory leaks.
- Memory usage increases cumulatively with each image selection, suggesting that the previous image is not being disposed of correctly and remains in memory.
### Screenshots
_No response_
### Code Platform
- [ ] UWP
- [x] WinAppSDK / WinUI 3
- [ ] Web Assembly (WASM)
- [ ] Android
- [ ] iOS
- [ ] MacOS
- [ ] Linux / GTK
### Windows Build Number
- [ ] Windows 10 1809 (Build 17763)
- [ ] Windows 10 1903 (Build 18362)
- [ ] Windows 10 1909 (Build 18363)
- [ ] Windows 10 2004 (Build 19041)
- [ ] Windows 10 20H2 (Build 19042)
- [ ] Windows 10 21H1 (Build 19043)
- [ ] Windows 10 21H2 (Build 19044)
- [ ] Windows 10 22H2 (Build 19045)
- [ ] Windows 11 21H2 (Build 22000)
- [ ] Other (specify)
### Other Windows Build number
_No response_
### App minimum and target SDK version
- [ ] Windows 10, version 1809 (Build 17763)
- [ ] Windows 10, version 1903 (Build 18362)
- [ ] Windows 10, version 1909 (Build 18363)
- [ ] Windows 10, version 2004 (Build 19041)
- [ ] Windows 10, version 2104 (Build 20348)
- [ ] Windows 11, version 22H2 (Build 22000)
- [ ] Other (specify)
### Other SDK version
_No response_
### Visual Studio Version
_No response_
### Visual Studio Build Number
_No response_
### Device form factor
_No response_
### Additional context
_No response_
### Help us help you
Yes, but only if others can assist.
Guida per i contributori
Apri la guida per i contributori
Direzione di ricerca
Start by reproducing the issue with the provided MainWindow XAML/C# sample and a high-resolution image, focusing on repeated calls to imageCropper.LoadImageFromFile(file). Inspect the ImageCropper implementation and its Reset path to determine where previous image resources remain referenced. Done means repeated selections no longer cause cumulative memory growth or an unexpected exit.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- csharp
- Ambito
- desktop
- Tipo di issue
- Bug
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Ferma
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 35/100