Convert Content view to image

DeepakDYDeepakDY INMember ✭✭✭

Hello Developers

It is possible to convert content view to Image?

Best Answers

  • JarvanJarvan Xamurai
    edited July 11 Accepted Answer

    @DeepakDY
    Create a view renderer and add the feature code:
    1.Get the view 2.Create and draw the bitmap 3.Save the file.
    The image of ContentView will be saved to the specified path when you call the command. You can refer to the following code.
    page.xaml

    <local:View1 x:Name="root">
    </local:View1>
    
    root.OnDrawBitmap.Invoke(root, new EventArgs());
    

    view.xaml.cs

    public partial class View1 : ContentView
    {
        public EventHandler OnDrawBitmap;
        public View1()
        {
            InitializeComponent();
        }
    }
    

    view_renderer.cs

    public class MyViewRenderer : ViewRenderer<View1, Android.Views.View>
    {
        public MyViewRenderer(Context context) : base(context)
        {
        }
    
        protected override void OnElementChanged(ElementChangedEventArgs<View1> e)
        {
            base.OnElementChanged(e);
            if (e.NewElement != null)
            {
                e.NewElement.OnDrawBitmap += NewElement_OnDrawBitmap;
            }
        }
    
        private void NewElement_OnDrawBitmap(object sender, EventArgs e)
        {
            if (this.ViewGroup != null)
            {
                //get the subview
                Android.Views.View subView = ViewGroup.GetChildAt(0);
                int width = subView.Width;
                int height = subView.Height;
    
                //create and draw the bitmap
                Bitmap b = Bitmap.CreateBitmap(width, height, Bitmap.Config.Argb8888);
                Canvas c = new Canvas(b);
                ViewGroup.Draw(c);
    
                //save the bitmap to file
                SaveBitmapToFile(b);
            }
        }
    
        private void SaveBitmapToFile(Bitmap bm)
        {
            RequestStoragePermission();
    
            var sdCardPath = Android.App.Application.Context.GetExternalFilesDir(null).ToString();
            //var sdCardPath = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
            var filePath = System.IO.Path.Combine(sdCardPath, "test.png");
    
            var stream = new FileStream(filePath, FileMode.OpenOrCreate);
            bm.Compress(Bitmap.CompressFormat.Png, 100, stream);
            stream.Close();
        }
    
        private void RequestStoragePermission()
        {
            var activity = Forms.Context as MainActivity;
            if (activity.CheckSelfPermission(Android.Manifest.Permission.WriteExternalStorage) == Permission.Granted)
            {
                return;
            }
            else
            {
                ActivityCompat.RequestPermissions(activity, new string[] { Android.Manifest.Permission.WriteExternalStorage }, 1);
            }
        }
    }
    
  • DeepakDYDeepakDY IN ✭✭✭
    Accepted Answer

    Hello @yelinzh

    I used your code and it's working for convert content view to image.
    I don't want to save image so that according to my end.

    =>Firstly create content view

      [XamlCompilation(XamlCompilationOptions.Compile)]
        public partial class View1 : ContentView
        {
            public EventHandler OnDrawBitmap;
            public View1()
            {
                try
                {
                    InitializeComponent();
                }
                catch (Exception ex)
                {
    
                    throw;
                }
            }
        }
    

    => Then Create custom render

    [assembly: ExportRenderer(typeof(View1), typeof(MyViewRenderer))]
    namespace Projectname.Droid.Renders
    {
        public class MyViewRenderer : ViewRenderer<View1, Android.Views.View>
        {
            public MyViewRenderer(Context context) : base(context)
            {
            }
    
            protected override void OnElementChanged(ElementChangedEventArgs<View1> e)
            {
                base.OnElementChanged(e);
                if (e.NewElement != null)
                {
                    e.NewElement.OnDrawBitmap += NewElement_OnDrawBitmap;
                }
            }
    
            private void NewElement_OnDrawBitmap(object sender, EventArgs e)
            {
                if (this.ViewGroup != null)
                {
                    //get the subview
                    Android.Views.View subView = ViewGroup.GetChildAt(0);
                    int width = subView.Width;
                    int height = subView.Height;
    
                    //create and draw the bitmap
                    Bitmap b = Bitmap.CreateBitmap(width, height, Bitmap.Config.Argb8888);
                    Canvas c = new Canvas(b);
                    ViewGroup.Draw(c);
    
                    //save the bitmap to file
                   var bytes = SaveBitmapToFile(b);
                   string ImageBsae64 = Convert.ToBase64String(bytes);
                }
            }
    
            private byte[] SaveBitmapToFile(Bitmap bm)
            {
                MemoryStream ms = new MemoryStream();
                bm.Compress(Bitmap.CompressFormat.Png, 100, ms);
                return ms.ToArray();
            }
        }
    }
    

    => Create a content page and call content view and a button

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:d="http://xamarin.com/schemas/2014/forms/design"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                 mc:Ignorable="d"
                  xmlns:view="clr-namespace:ProjectName"
                 x:Class="ProjectName.TestPage">
        <ContentPage.Content>
            <Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
                <Grid.RowDefinitions>
                    <RowDefinition Height="*"/>
                    <RowDefinition Height="70"/>
                </Grid.RowDefinitions>
                <view:View1 x:Name="root" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"/>
                <Button Grid.Row="1" BackgroundColor="DarkSeaGreen" Clicked="Button_Clicked" 
                        Text="Click" FontSize="17" FontAttributes="Bold" Margin="10"/>
            </Grid>
        </ContentPage.Content>
    </ContentPage>
    

    => then call method in button click and get base64 string.

    private void Button_Clicked(object sender, EventArgs e)
            {
              root.OnDrawBitmap.Invoke(root, new EventArgs());
            }
    

    then check base64 string on webside.

Answers

  • JarvanJarvan Member, Xamarin Team Xamurai
    edited July 11 Accepted Answer

    @DeepakDY
    Create a view renderer and add the feature code:
    1.Get the view 2.Create and draw the bitmap 3.Save the file.
    The image of ContentView will be saved to the specified path when you call the command. You can refer to the following code.
    page.xaml

    <local:View1 x:Name="root">
    </local:View1>
    
    root.OnDrawBitmap.Invoke(root, new EventArgs());
    

    view.xaml.cs

    public partial class View1 : ContentView
    {
        public EventHandler OnDrawBitmap;
        public View1()
        {
            InitializeComponent();
        }
    }
    

    view_renderer.cs

    public class MyViewRenderer : ViewRenderer<View1, Android.Views.View>
    {
        public MyViewRenderer(Context context) : base(context)
        {
        }
    
        protected override void OnElementChanged(ElementChangedEventArgs<View1> e)
        {
            base.OnElementChanged(e);
            if (e.NewElement != null)
            {
                e.NewElement.OnDrawBitmap += NewElement_OnDrawBitmap;
            }
        }
    
        private void NewElement_OnDrawBitmap(object sender, EventArgs e)
        {
            if (this.ViewGroup != null)
            {
                //get the subview
                Android.Views.View subView = ViewGroup.GetChildAt(0);
                int width = subView.Width;
                int height = subView.Height;
    
                //create and draw the bitmap
                Bitmap b = Bitmap.CreateBitmap(width, height, Bitmap.Config.Argb8888);
                Canvas c = new Canvas(b);
                ViewGroup.Draw(c);
    
                //save the bitmap to file
                SaveBitmapToFile(b);
            }
        }
    
        private void SaveBitmapToFile(Bitmap bm)
        {
            RequestStoragePermission();
    
            var sdCardPath = Android.App.Application.Context.GetExternalFilesDir(null).ToString();
            //var sdCardPath = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
            var filePath = System.IO.Path.Combine(sdCardPath, "test.png");
    
            var stream = new FileStream(filePath, FileMode.OpenOrCreate);
            bm.Compress(Bitmap.CompressFormat.Png, 100, stream);
            stream.Close();
        }
    
        private void RequestStoragePermission()
        {
            var activity = Forms.Context as MainActivity;
            if (activity.CheckSelfPermission(Android.Manifest.Permission.WriteExternalStorage) == Permission.Granted)
            {
                return;
            }
            else
            {
                ActivityCompat.RequestPermissions(activity, new string[] { Android.Manifest.Permission.WriteExternalStorage }, 1);
            }
        }
    }
    
  • DeepakDYDeepakDY INMember ✭✭✭
    Accepted Answer

    Hello @yelinzh

    I used your code and it's working for convert content view to image.
    I don't want to save image so that according to my end.

    =>Firstly create content view

      [XamlCompilation(XamlCompilationOptions.Compile)]
        public partial class View1 : ContentView
        {
            public EventHandler OnDrawBitmap;
            public View1()
            {
                try
                {
                    InitializeComponent();
                }
                catch (Exception ex)
                {
    
                    throw;
                }
            }
        }
    

    => Then Create custom render

    [assembly: ExportRenderer(typeof(View1), typeof(MyViewRenderer))]
    namespace Projectname.Droid.Renders
    {
        public class MyViewRenderer : ViewRenderer<View1, Android.Views.View>
        {
            public MyViewRenderer(Context context) : base(context)
            {
            }
    
            protected override void OnElementChanged(ElementChangedEventArgs<View1> e)
            {
                base.OnElementChanged(e);
                if (e.NewElement != null)
                {
                    e.NewElement.OnDrawBitmap += NewElement_OnDrawBitmap;
                }
            }
    
            private void NewElement_OnDrawBitmap(object sender, EventArgs e)
            {
                if (this.ViewGroup != null)
                {
                    //get the subview
                    Android.Views.View subView = ViewGroup.GetChildAt(0);
                    int width = subView.Width;
                    int height = subView.Height;
    
                    //create and draw the bitmap
                    Bitmap b = Bitmap.CreateBitmap(width, height, Bitmap.Config.Argb8888);
                    Canvas c = new Canvas(b);
                    ViewGroup.Draw(c);
    
                    //save the bitmap to file
                   var bytes = SaveBitmapToFile(b);
                   string ImageBsae64 = Convert.ToBase64String(bytes);
                }
            }
    
            private byte[] SaveBitmapToFile(Bitmap bm)
            {
                MemoryStream ms = new MemoryStream();
                bm.Compress(Bitmap.CompressFormat.Png, 100, ms);
                return ms.ToArray();
            }
        }
    }
    

    => Create a content page and call content view and a button

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:d="http://xamarin.com/schemas/2014/forms/design"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                 mc:Ignorable="d"
                  xmlns:view="clr-namespace:ProjectName"
                 x:Class="ProjectName.TestPage">
        <ContentPage.Content>
            <Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
                <Grid.RowDefinitions>
                    <RowDefinition Height="*"/>
                    <RowDefinition Height="70"/>
                </Grid.RowDefinitions>
                <view:View1 x:Name="root" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"/>
                <Button Grid.Row="1" BackgroundColor="DarkSeaGreen" Clicked="Button_Clicked" 
                        Text="Click" FontSize="17" FontAttributes="Bold" Margin="10"/>
            </Grid>
        </ContentPage.Content>
    </ContentPage>
    

    => then call method in button click and get base64 string.

    private void Button_Clicked(object sender, EventArgs e)
            {
              root.OnDrawBitmap.Invoke(root, new EventArgs());
            }
    

    then check base64 string on webside.

Sign In or Register to comment.