Reputation: 51
I am trying to get an image in the shape of rectangle with rounded Cornes. I have tried to use nugget fftransformations and frame. So far I am not getting the result I want. Using the nugget turns the image into square no matter what size I give to it. Using frame for some reason doesn't actually round the corners. enter image description here
<StackLayout VerticalOptions="CenterAndExpand">
<ffimageloading:CachedImage VerticalOptions="CenterAndExpand"
WidthRequest="530" HeightRequest="334"
DownsampleToViewSize="true"
Source = "http://loremflickr.com/530/334/nature?filename=simple.jpg">
<ffimageloading:CachedImage.Transformations>
<fftransformations:RoundedTransformation Radius="10"/>
</ffimageloading:CachedImage.Transformations>
</ffimageloading:CachedImage>
<ffimageloading:CachedImage VerticalOptions="CenterAndExpand"
WidthRequest="530" HeightRequest="334"
DownsampleToViewSize="true"
Source = "http://loremflickr.com/530/334/nature?filename=simple.jpg">
<ffimageloading:CachedImage.Transformations>
<fftransformations:CornersTransformation CornersTransformType="AllRounded"/>
</ffimageloading:CachedImage.Transformations>
</ffimageloading:CachedImage>
<Grid VerticalOptions="CenterAndExpand">
<Frame Padding="0" WidthRequest="530" HeightRequest="334"
HorizontalOptions="Center"
VerticalOptions="Center" CornerRadius="20" >
<Image Source = "http://loremflickr.com/530/330/nature?filename=simple.jpg" Aspect="AspectFill" />
</Frame>
</Grid>
</StackLayout>
Upvotes: 1
Views: 570
Reputation: 933
Some time ago I needed corner effects on other controls. And it applies to image too. All you need is to create Effect:
public class RoundCornersEffect : RoutingEffect
{
public RoundCornersEffect() : base($"MySuperApp.{nameof(RoundCornersEffect)}")
{
}
public static readonly BindableProperty CornerRadiusProperty =
BindableProperty.CreateAttached(
"CornerRadius",
typeof(int),
typeof(RoundCornersEffect),
0,
propertyChanged: OnCornerRadiusChanged);
public static int GetCornerRadius(BindableObject view) =>
(int)view.GetValue(CornerRadiusProperty);
public static void SetCornerRadius(BindableObject view, int value) =>
view.SetValue(CornerRadiusProperty, value);
private static void OnCornerRadiusChanged(BindableObject bindable, object oldValue, object newValue)
{
if (!(bindable is View view))
return;
var cornerRadius = (int)newValue;
var effect = view.Effects.OfType<RoundCornersEffect>().FirstOrDefault();
if (cornerRadius > 0 && effect == null)
view.Effects.Add(new RoundCornersEffect());
if (cornerRadius == 0 && effect != null)
view.Effects.Remove(effect);
}
}
And implement it on both platforms:
IOS:
public class RoundCornersEffectIOS : PlatformEffect
{
protected override void OnAttached()
{
try
{
PrepareContainer();
SetCornerRadius();
}
catch (Exception e)
{
Debug.WriteLine(e);
}
}
protected override void OnDetached()
{
try
{
Container.Layer.CornerRadius = new nfloat(0);
}
catch (Exception e)
{
Debug.WriteLine(e);
}
}
protected override void OnElementPropertyChanged(PropertyChangedEventArgs args)
{
if (args.PropertyName == RoundCornersEffect.CornerRadiusProperty.PropertyName)
SetCornerRadius();
}
private void PrepareContainer()
{
Container.ClipsToBounds = true;
Container.Layer.AllowsEdgeAntialiasing = true;
Container.Layer.EdgeAntialiasingMask = CAEdgeAntialiasingMask.All;
}
private void SetCornerRadius()
{
var cornerRadius = RoundCornersEffect.GetCornerRadius(Element);
Container.Layer.CornerRadius = new nfloat(cornerRadius);
}
}
Droid:
public class RoundCornersEffectDroid : PlatformEffect
{
private Android.Views.View View => Control ?? Container;
protected override void OnAttached()
{
try
{
PrepareContainer();
SetCornerRadius();
}
catch (Exception e)
{
Debug.WriteLine(e);
}
}
protected override void OnDetached()
{
try
{
View.OutlineProvider = ViewOutlineProvider.Background;
}
catch (Exception e)
{
Debug.WriteLine(e);
}
}
protected override void OnElementPropertyChanged(PropertyChangedEventArgs args)
{
if (args.PropertyName == RoundCornersEffect.CornerRadiusProperty.PropertyName)
SetCornerRadius();
}
private void PrepareContainer()
{
View.ClipToOutline = true;
}
private void SetCornerRadius()
{
var cornerRadius = RoundCornersEffect.GetCornerRadius(Element) * GetDensity();
View.OutlineProvider = new RoundedOutlineProvider(cornerRadius);
}
private static double GetDensity() =>
DeviceDisplay.MainDisplayInfo.Density;
private class RoundedOutlineProvider : ViewOutlineProvider
{
private readonly double _radius;
public RoundedOutlineProvider(double radius)
{
_radius = radius;
}
public override void GetOutline(Android.Views.View view, Outline outline)
{
outline?.SetRoundRect(0, 0, view.Width, view.Height, (float)_radius);
}
}
}
Then you can use it in control:
<Image Source="mylogo.png" VerticalOptions="Center" Aspect="AspectFit" myeffects:RoundCornersEffect.CornerRadius="5"/>
Upvotes: 1