CommunityToolkit / CommunityToolkit/Windows

Memory Management with `ImageCropper` Control

Aperta
#460 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
bug components::controls::imagecropper
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:
![image](https://github.com/user-attachments/assets/720a6f15-6236-45a7-bcb5-a3314ab6ba86)

- After 2nd image selection:
![image](https://github.com/user-attachments/assets/a96caf11-8603-4bf6-befd-8a6608ce33c7)

- After 3rd image selection:
![image](https://github.com/user-attachments/assets/429be232-a531-482a-af54-6241f33004fc)

- After 4th image selection:
![image](https://github.com/user-attachments/assets/3540d1a0-1824-4cac-a8a8-e0e2b97db5b1)

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

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.