Jan49
Jan49

Reputation: 1818

CircularImage in Xamarin.Forms

I need to have Image control in Xamarin.Forms with rounded corners. But I did not find any property that could make it. How to have circular Image ?

Upvotes: 5

Views: 4675

Answers (3)

Sreeraj
Sreeraj

Reputation: 2434

If you need a solution using Custom Renderers (to tweak the control the way you want), here is my implementation for that.

public class ImageCircle:Image
{
    public ImageCircle ()
    {
    }
}

[assembly: ExportRenderer(typeof(ImageCircle), typeof(ImageCircleRenderer))]
namespace myNamespace.Droid
{
public class ImageCircleRenderer:ImageRenderer
{
    public ImageCircleRenderer ()
    {
    }

    protected override void OnElementChanged(ElementChangedEventArgs<Image>  e)
    {
        base.OnElementChanged(e);

        if (e.OldElement == null)
        {

            if ((int)Android.OS.Build.VERSION.SdkInt < 20)
                SetLayerType(Android.Views.LayerType.Software, null);
        }
    }
    protected override bool DrawChild(Canvas canvas, global::Android.Views.View child, long drawingTime)
    {
        try
        {
            var radius = Math.Min(Width, Height) / 2;
            var strokeWidth = 10;
            radius -= strokeWidth / 2;

            //Create path to clip
            var path = new Path();
            path.AddCircle(Width / 2, Height / 2, radius, Path.Direction.Ccw);
            canvas.Save();
            canvas.ClipPath(path);

            var result = base.DrawChild(canvas, child, drawingTime);

            canvas.Restore();

            // Create path for circle border
            path = new Path();
            path.AddCircle(Width / 2, Height / 2, radius, Path.Direction.Ccw);

            var paint = new Paint();
            paint.AntiAlias = true;
            paint.StrokeWidth = 5;
            paint.SetStyle(Paint.Style.Stroke);
            paint.Color = global::Android.Graphics.Color.White;

            canvas.DrawPath(path, paint);

            //Properly dispose
            paint.Dispose();
            path.Dispose();
            return result;
        }
        catch (Exception ex)
        {
            Console.WriteLine("Unable to create circle image: " + ex);
        }

        return base.DrawChild(canvas, child, drawingTime);
    }
}
}

[assembly: ExportRenderer(typeof(ImageCircle), typeof(ImageCircleRenderer))]
namespace LifesTopTen.iOS
{
public class ImageCircleRenderer:ImageRenderer
{
    public ImageCircleRenderer ()
    {
    }
    private void CreateCircle()
    {
        try
        {
            double min = Math.Min(Element.Width, Element.Height);
            Control.Layer.CornerRadius = (float)(min / 2.0);
            Control.Layer.MasksToBounds = false;
            Control.Layer.BorderColor = Color.White.ToCGColor();
            Control.Layer.BorderWidth = 3;
            Control.ClipsToBounds = true;
        }
        catch(Exception ex)
        {
            Console.WriteLine ("Unable to create circle image: " + ex);
        }

    }
    protected override void OnElementChanged (ElementChangedEventArgs<Image> e)
    {
        base.OnElementChanged (e);

        if (e.OldElement != null || Element == null)
            return;

        CreateCircle();
    }


    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);

        if (e.PropertyName == VisualElement.HeightProperty.PropertyName ||
            e.PropertyName == VisualElement.WidthProperty.PropertyName)
        {
            CreateCircle();
        }
    }

}
}

Upvotes: 2

matthewrdev
matthewrdev

Reputation: 12180

I use the FFImageLoading libraries CachedImage control with a circle transformation for circle images:

<ffimageloading:CachedImage  
        DownsampleToViewSize="true"
        Aspect="AspectFill"
        Source = "{Binding Image}"
        LoadingPlaceholder = "{Binding DefaultImage}"
        ErrorPlaceholder = "{Binding DefaultImage}">
    <ffimageloading:CachedImage.Transformations>
        <fftransformations:CircleTransformation />
    </ffimageloading:CachedImage.Transformations>
</ffimageloading:CachedImage>

enter image description here

Upvotes: 17

Giorgi
Giorgi

Reputation: 30873

You can use Image Circle Control Plugin

<controls:CircleImage Source="{Binding Image}" Aspect="AspectFill">
  <controls:CircleImage.WidthRequest>
    <OnPlatform x:TypeArguments="x:Double"
      iOS="55"
      Android="55"
      WinPhone="75"/>
   </controls:CircleImage.WidthRequest>
<controls:CircleImage.HeightRequest>
    <OnPlatform x:TypeArguments="x:Double"
      iOS="55"
      Android="55"
      WinPhone="75"/>
   </controls:CircleImage.HeightRequest>
</controls:CircleImage>

enter image description here

Read more at Project github readme

You can also use CircleImage from Xamarin-Forms-Labs project.

Upvotes: 6

Related Questions