Skip to content

Commit 0c8d77f

Browse files
committed
feat: CropAvatar switch image memory management
1 parent 0165541 commit 0c8d77f

1 file changed

Lines changed: 106 additions & 7 deletions

File tree

src/WPFDevelopers.Shared/Controls/CropAvatar/CropAvatar.cs

Lines changed: 106 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using System;
2-
using System.Diagnostics;
2+
using System.Threading.Tasks;
33
using System.Windows;
44
using System.Windows.Controls;
55
using System.Windows.Input;
@@ -16,7 +16,7 @@ namespace WPFDevelopers.Controls
1616
[TemplatePart(Name = GridTemplateName, Type = typeof(SmallPanel))]
1717
[TemplatePart(Name = ReplaceButtonTemplateName, Type = typeof(Button))]
1818
[TemplatePart(Name = AddButtonTemplateName, Type = typeof(Button))]
19-
public class CropAvatar : Control
19+
public class CropAvatar : Control, IDisposable
2020
{
2121
private const string CanvasTemplateName = "PART_Canvas";
2222
private const string ImageTemplateName = "PART_Image";
@@ -33,6 +33,8 @@ public class CropAvatar : Control
3333
private BitmapFrame _bitmapFrame;
3434
private Canvas _canvas;
3535
private CroppedBitmap _crop;
36+
private WriteableBitmap _cachedResult;
37+
private bool _disposed = false;
3638
private SmallPanel _grid;
3739
private Image _image;
3840
private int _initialX, _initialY, _voffsetX, _voffsetY;
@@ -91,8 +93,15 @@ public override void OnApplyTemplate()
9193
_addButton.Click -= OnAddButton_Click;
9294
_addButton.Click += OnAddButton_Click;
9395
}
96+
Unloaded -= OnCropAvatar_Unloaded;
97+
Unloaded += OnCropAvatar_Unloaded;
9498
}
9599

100+
private void OnCropAvatar_Unloaded(object sender, RoutedEventArgs e)
101+
{
102+
Dispose();
103+
}
104+
96105
private void OnCanvas_Loaded(object sender, RoutedEventArgs e)
97106
{
98107
if (sender is Canvas canvas)
@@ -190,15 +199,31 @@ private void OnAddButton_Click(object sender, RoutedEventArgs e)
190199

191200
private void InitialImage()
192201
{
202+
CleanupOldResources();
193203
_vNewStartX = 0;
194204
_vNewStartY = 0;
195205
var uri = Helper.ImageUri();
196206
if (uri == null) return;
197-
var bitmap = new BitmapImage();
198-
bitmap.BeginInit();
199-
bitmap.CacheOption = BitmapCacheOption.OnLoad;
200-
bitmap.UriSource = uri;
201-
bitmap.EndInit();
207+
BitmapImage bitmap = null;
208+
try
209+
{
210+
bitmap = new BitmapImage();
211+
bitmap.BeginInit();
212+
bitmap.CacheOption = BitmapCacheOption.OnLoad;
213+
bitmap.UriSource = uri;
214+
bitmap.EndInit();
215+
if (bitmap.CanFreeze)
216+
bitmap.Freeze();
217+
}
218+
catch
219+
{
220+
throw;
221+
}
222+
223+
if (bitmap == null || bitmap.Width == 0 || bitmap.Height == 0)
224+
{
225+
return;
226+
}
202227
if (bitmap.Height > bitmap.Width)
203228
{
204229
var scale = bitmap.Width / _path.Width;
@@ -253,5 +278,79 @@ private void InitialImage()
253278
}
254279
OutImageSource = _crop;
255280
}
281+
282+
private void CleanupOldResources()
283+
{
284+
if (_bitmapFrame != null)
285+
{
286+
_bitmapFrame = null;
287+
}
288+
289+
if (_crop != null)
290+
{
291+
_crop = null;
292+
}
293+
294+
#if NET40
295+
Task.Factory.StartNew(() =>
296+
{
297+
GC.Collect(2);
298+
});
299+
#else
300+
Task.Run(() =>
301+
{
302+
GC.Collect(2, GCCollectionMode.Forced);
303+
});
304+
#endif
305+
}
306+
307+
public void Dispose()
308+
{
309+
Dispose(true);
310+
GC.SuppressFinalize(this);
311+
}
312+
313+
protected virtual void Dispose(bool disposing)
314+
{
315+
if (!_disposed)
316+
{
317+
if (disposing)
318+
{
319+
CleanupOldResources();
320+
321+
if (_image != null)
322+
{
323+
_image.Source = null;
324+
}
325+
if (_canvas != null)
326+
{
327+
_canvas.Loaded -= OnCanvas_Loaded;
328+
}
329+
if (_image != null)
330+
{
331+
_image.MouseDown -= OnImage_MouseDown;
332+
_image.MouseMove -= OnImage_MouseMove;
333+
_image.MouseUp -= OnImage_MouseUp;
334+
_image.MouseLeave -= OnImage_MouseLeave;
335+
}
336+
if (_replaceButton != null)
337+
{
338+
_replaceButton.Click -= OnReplaceButton_Click;
339+
}
340+
if (_addButton != null)
341+
{
342+
_addButton.Click -= OnAddButton_Click;
343+
}
344+
Unloaded -= OnCropAvatar_Unloaded;
345+
}
346+
_disposed = true;
347+
}
348+
}
349+
350+
351+
~CropAvatar()
352+
{
353+
Dispose(false);
354+
}
256355
}
257356
}

0 commit comments

Comments
 (0)