Skip to content

Commit

Permalink
GTK: call Pixbuf ctor on MainThread for LoadImageAsync functions
Browse files Browse the repository at this point in the history
This fix avoid threading problems caused by calling Pixbuf ctor from outside
of the MainThread.

Upstream PR: xamarin#15503
  • Loading branch information
parhamsaremi authored and knocte committed Aug 11, 2022
1 parent 94acebb commit 456ff97
Showing 1 changed file with 24 additions and 9 deletions.
33 changes: 24 additions & 9 deletions Xamarin.Forms.Platform.GTK/Renderers/ImageRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ public interface IImageSourceHandler : IRegisterable

public sealed class FileImageSourceHandler : IImageSourceHandler
{
public Task<Pixbuf> LoadImageAsync(
public async Task<Pixbuf> LoadImageAsync(
ImageSource imagesource,
CancellationToken cancelationToken = default(CancellationToken),
float scale = 1f)
Expand All @@ -188,12 +188,15 @@ public sealed class FileImageSourceHandler : IImageSourceHandler

if (File.Exists(imagePath))
{
image = new Pixbuf(imagePath);
await Device.InvokeOnMainThreadAsync(() =>
{
image = new Pixbuf(imagePath);
});
}
}
}

return Task.FromResult(image);
return image;
}
}

Expand All @@ -210,7 +213,12 @@ public async Task<Pixbuf> LoadImageAsync(ImageSource imagesource, CancellationTo
.GetStreamAsync(cancelationToken).ConfigureAwait(false))
{
if (streamImage != null)
image = new Pixbuf(streamImage);
{
await Device.InvokeOnMainThreadAsync(() =>
{
image = new Pixbuf(streamImage);
});
}
}

return image;
Expand Down Expand Up @@ -238,7 +246,10 @@ public sealed class UriImageSourceHandler : IImageSourceHandler
return null;
}

image = new Pixbuf(streamImage);
await Device.InvokeOnMainThreadAsync(() =>
{
image = new Pixbuf(streamImage);
});
}

return image;
Expand All @@ -248,13 +259,13 @@ public sealed class UriImageSourceHandler : IImageSourceHandler

public sealed class FontImageSourceHandler : IImageSourceHandler
{
public Task<Pixbuf> LoadImageAsync(ImageSource imageSource,
public async Task<Pixbuf> LoadImageAsync(ImageSource imageSource,
CancellationToken cancellationToken = new CancellationToken(), float scale = 1)
{
if (!(imageSource is FontImageSource fontImageSource))
return null;

Pixbuf pixbuf;
Pixbuf pixbuf = null;
using (var bmp = new Bitmap((int)fontImageSource.Size, (int)fontImageSource.Size))
{
using (var g = Graphics.FromImage(bmp))
Expand All @@ -270,11 +281,15 @@ public sealed class FontImageSourceHandler : IImageSourceHandler
using (var stream = new MemoryStream())
{
bmp.Save(stream, ImageFormat.Jpeg);
pixbuf = new Pixbuf(stream.ToArray());
await Device.InvokeOnMainThreadAsync(() =>
{
pixbuf = new Pixbuf(stream.ToArray());
});

}
}

return Task.FromResult(pixbuf);
return pixbuf;
}

static FontFamily GetFontFamily(FontImageSource fontImageSource)
Expand Down

0 comments on commit 456ff97

Please sign in to comment.