Skip to content

Commit 533cf74

Browse files
SyedAbdulAzeemSF4852PureWeen
authored andcommitted
[Android, iOS] Fix for the Resize method does not dispose the original image, even when disposeOriginal is set to true (#29936)
* Fix for original image disposal when disposeOriginal is true in Resize and Downsize methods on Android and iOS * Updated the fix for iOS, and modified the test case to reflect the changes * Updated the issue link in test case
1 parent bba2fac commit 533cf74

File tree

4 files changed

+135
-2
lines changed

4 files changed

+135
-2
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using System.Reflection;
2+
using Microsoft.Maui.Graphics.Platform;
3+
using IImage = Microsoft.Maui.Graphics.IImage;
4+
5+
namespace Controls.TestCases.HostApp.Issues;
6+
7+
[Issue(IssueTracker.Github, 21886, "The original image remains undisposed even after setting disposeOriginal to true in the Resize and Downsize methods", PlatformAffected.Android | PlatformAffected.iOS)]
8+
public class Issue21886 : ContentPage
9+
{
10+
Label _originalImageStatusLabel;
11+
12+
public Issue21886()
13+
{
14+
_originalImageStatusLabel = new Label
15+
{
16+
AutomationId = "OriginalImageStatusLabel",
17+
Text = "Status of Original Image Disposal"
18+
};
19+
20+
VerticalStackLayout stackLayout = new VerticalStackLayout
21+
{
22+
Children =
23+
{
24+
CreateButton("Resize", OnResize),
25+
CreateButton("DownSize", OnDownSize),
26+
_originalImageStatusLabel,
27+
}
28+
};
29+
30+
Content = new ScrollView { Content = stackLayout };
31+
}
32+
33+
Button CreateButton(string text, EventHandler handler)
34+
{
35+
Button button = new Button
36+
{
37+
AutomationId = $"Issue21886{text}Btn",
38+
Text = text,
39+
HorizontalOptions = LayoutOptions.Fill
40+
};
41+
42+
button.Clicked += handler;
43+
return button;
44+
}
45+
46+
async Task<IImage> LoadImageAsync()
47+
{
48+
var assembly = GetType().GetTypeInfo().Assembly;
49+
using var stream = assembly.GetManifestResourceStream("Controls.TestCases.HostApp.Resources.Images.royals.png");
50+
return await Task.FromResult(PlatformImage.FromStream(stream));
51+
}
52+
53+
async void OnResize(object sender, EventArgs e)
54+
{
55+
var image = await LoadImageAsync();
56+
var res = image.Resize(10, 10, ResizeMode.Fit, true);
57+
58+
UpdateStatusLabels(res, image, "Resize");
59+
}
60+
61+
async void OnDownSize(object sender, EventArgs e)
62+
{
63+
var image = await LoadImageAsync();
64+
var res = image.Downsize(10, 10, true);
65+
66+
UpdateStatusLabels(res, image, "Downsize");
67+
}
68+
69+
void UpdateStatusLabels(IImage resultImage, IImage originalImage, string operation)
70+
{
71+
_originalImageStatusLabel.Text = TryAccessImage(originalImage)
72+
? "Success"
73+
: originalImage.Width == 0 && originalImage.Height == 0 ? "Success" : "Failure";
74+
}
75+
76+
bool TryAccessImage(IImage image)
77+
{
78+
try
79+
{
80+
var _ = image.Width;
81+
return false;
82+
}
83+
catch (ObjectDisposedException)
84+
{
85+
return true;
86+
}
87+
}
88+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#if TEST_FAILS_ON_WINDOWS // Issue Link - https://github.com/dotnet/maui/issues/16767
2+
using NUnit.Framework;
3+
using UITest.Appium;
4+
using UITest.Core;
5+
6+
namespace Microsoft.Maui.TestCases.Tests.Issues;
7+
8+
public class Issue21886 : _IssuesUITest
9+
{
10+
public Issue21886(TestDevice device) : base(device)
11+
{
12+
}
13+
14+
public override string Issue => "The original image remains undisposed even after setting disposeOriginal to true in the Resize and Downsize methods";
15+
16+
[Test]
17+
[Category(UITestCategories.GraphicsView)]
18+
public void VerifyOriginalImageBeingDisposed()
19+
{
20+
App.WaitForElement("OriginalImageStatusLabel");
21+
App.Tap("Issue21886ResizeBtn");
22+
23+
var resizeLabelText = App.FindElement("OriginalImageStatusLabel").GetText();
24+
Assert.That(resizeLabelText, Is.EqualTo("Success"));
25+
26+
App.Tap("Issue21886DownSizeBtn");
27+
28+
var downsizeLabelText = App.FindElement("OriginalImageStatusLabel").GetText();
29+
Assert.That(downsizeLabelText, Is.EqualTo("Success"));
30+
}
31+
}
32+
#endif

src/Graphics/src/Graphics/Platforms/Android/PlatformImage.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ public PlatformImage(Bitmap bitmap)
1515
_bitmap = bitmap;
1616
}
1717

18-
public float Width => _bitmap.Width;
18+
public float Width => _bitmap?.Width ?? 0;
1919

20-
public float Height => _bitmap.Height;
20+
public float Height => _bitmap?.Height ?? 0;
2121

2222
public IImage Downsize(float maxWidthOrHeight, bool disposeOriginal = false)
2323
{
@@ -83,6 +83,13 @@ public IImage Resize(float width, float height, ResizeMode resizeMode = ResizeMo
8383
}
8484

8585
context.Canvas.DrawImage(this, x, y, w, h);
86+
87+
if (disposeOriginal)
88+
{
89+
_bitmap.Recycle();
90+
_bitmap.Dispose();
91+
}
92+
8693
return context.Image;
8794
}
8895
}

src/Graphics/src/Graphics/Platforms/iOS/PlatformImage.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ public IImage Resize(float width, float height, ResizeMode resizeMode = ResizeMo
8484
}
8585

8686
context.Canvas.DrawImage(this, x, y, w, h);
87+
88+
if (disposeOriginal)
89+
{
90+
_image.Dispose();
91+
}
92+
8793
return context.Image;
8894
}
8995
}

0 commit comments

Comments
 (0)