Hello,
Strange error happening with SkiaSharp SKCanvasView on Android device emulators.
SKCanvasView implemeted in a contentView like this:
<StackLayout Orientation="Vertical" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" BackgroundColor="#414141" >
<skia:SKCanvasView x:Name="canvasView" Grid.Column="0" Grid.Row="0" PaintSurface="OnCanvasViewPaintSurface" Touch="OnCanvasTouch" EnableTouchEvents="True" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" BackgroundColor="#414141" />
</StackLayout>
When the contentView loads, I use a pre-defined _resourceId which is simply a string pointing at an embeddedResource image in the shared project.
The base image is 600px x 300px
Assembly assembly = GetType().GetTypeInfo().Assembly;
using (Stream stream = assembly.GetManifestResourceStream(_resourceID))
using (SKManagedStream skStream = new SKManagedStream(stream))
{
_resourceBitmap = SKBitmap.Decode(skStream);
}
After the constructor completes, the OnCanvasViewPaintSurface() method fires to draw the image onto the canvas.
Note the _resourceBitmap now used to fill the SKCanvasView control...
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
try
{
//base control size
var baseFrame = SKRect.Create(0, 0, info.Width, info.Height);
var imageSize = new SKSize(_resourceBitmap.Width, _resourceBitmap.Height);
var aspect = baseFrame.AspectFit(imageSize);
var pictureFrame = SKRect.Create(0, 0, aspect.Width, aspect.Height);
//expand control to the available area
canvasView.WidthRequest = pictureFrame.Width;
canvasView.HeightRequest = pictureFrame.Height;
var paint = new SKPaint { FilterQuality = SKFilterQuality.High };
paint.IsAntialias = true;
paint.IsStroke = true;
//load the base image
canvas.DrawBitmap(_resourceBitmap, pictureFrame, paint);
}
catch (Exception ex)
{
string s = ex.Message;
}
}
As already stated, _resourceBitmap is 600px x 300px.
The SKImageInfo info object shows an initial size of 40x40.
The SKRect pictureFrame used to transform the image when loaded in the DrawBitmap() method, is scaled using the aspect object. This enlarges as does the info object as the method is called each time, thus the image is animated as it opens and is displayed. Finally, the image is actually enlarged and displayed filling the space available to it. In the Nexus5x case, final dimensions are 1200x600.
Here's the issue - if I run this in a Nexus5x emulator using API 26 Android 8.0, the OnCanvasViewPaintSurface() is called 5 times as the SKCanvasView animates up to full view. No problems, works as expected.
If I run this in a 7" Tablet or 10" Tablet emulator also running API 26 Android 8.0, the OnCanvasViewPaintSurface() is only called twice and the base image is never displayed at it's full size and certainly never fills the space available.
No idea why this is happening. Same code, same OS version, different emulators, different display results.
Any ideas?
Questions:
How can I turn OFF animation on the SKCanvasView? it ALWAYS animates on opening.
I want it to load to max available size/space and only call the OnCanvasViewPaintSurface() once and not twice or five times... OR call/invoke the OnCanvasViewPaintSurface() method as many time as needed as long as it displays the image in full.
How can I determine the max size the SKCanvasView can expand to PRIOR to loading any image? This will vary from device to device obviously.
Any advice or insights would be welcome!
Thank you.