Forum Xamarin.Forms
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

Export Renderer of Canvas Android issues

So I created a small demo that can take a picture and be able to draw over it. later I will add the save functionality later .

the issue that I am having is when I display the image inside the canvas the size and orientation of the image does not fit the screen and if I change the orientation of my device the image disappear. when I add the bitmap to onSizechanged method I get an error.

Could Anyone help with this?

https://www.dropbox.com/s/nhnsr5208ea57gr/CanvasNativeTest.zip?dl=0

Best Answers

Answers

  • RichardPresleyRichardPresley USMember ✭✭

    Ok so I figured out how to change the size and orientation of bitmap.

     public Bitmap LoadAndResizeBitmap( string fileName, int width, int height)
            {
                // First we get the the dimensions of the file on disk
                BitmapFactory.Options options = new BitmapFactory.Options { InJustDecodeBounds = true };
                BitmapFactory.DecodeFile(fileName, options);
    
                // Next we calculate the ratio that we need to resize the image by
                // in order to fit the requested dimensions.
                int outHeight = options.OutHeight;
                int outWidth = options.OutWidth;
                int inSampleSize = 1;
    
                if (outHeight > height || outWidth > width)
                {
                    inSampleSize = outWidth > outHeight
                        ? outHeight / height
                            : outWidth / width;
                }
    
                // Now we will load the image and have BitmapFactory resize it for us.
                options.InSampleSize = inSampleSize;
                options.InJustDecodeBounds = false;
                Bitmap resizedBitmap = BitmapFactory.DecodeFile(fileName, options);
    
                // Images are being saved in landscape, so rotate them back to portrait if they were taken in portrait
                Matrix mtx = new Matrix();
                ExifInterface exif = new ExifInterface(fileName);
                string orientation = exif.GetAttribute(ExifInterface.TagOrientation);
    
                switch (orientation)
                {
                    case "6": // portrait
                        mtx.PreRotate(90);
                        resizedBitmap = Bitmap.CreateBitmap(resizedBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height, mtx, false);
                        mtx.Dispose();
                        mtx = null;
                        break;
                    case "3": // portrait
                        mtx.PreRotate(180);
                        resizedBitmap = Bitmap.CreateBitmap(resizedBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height, mtx, false);
                        mtx.Dispose();
                        mtx = null;
                        break;
                    case "1": // landscape
                        break;
                    default:
                        mtx.PreRotate(90);
                        resizedBitmap = Bitmap.CreateBitmap(resizedBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height, mtx, false);
                        mtx.Dispose();
                        mtx = null;
                        break;
                }
                var screenHeight = Resources.DisplayMetrics.HeightPixels;
                var screenWidth = Resources.DisplayMetrics.WidthPixels;
                var a = Bitmap.CreateScaledBitmap(resizedBitmap, screenWidth, screenHeight,false);
                resizedBitmap.Dispose();
                return a;
            }
    

    now I only got 2 issues:

    1.
    If I change my devices orientation and/or take multiple edited photos I get this error:
    Java.Lang.OutOfMemoryError: Failed to allocate a 63489036 byte allocation with 33542928 free bytes and 32MB until OOM

    2.
    How do you call a method or a function through a an export renderer?

    so how does my save button in my xamarin form content page call a method called save in my native Android view?

  • RichardPresleyRichardPresley USMember ✭✭

    @mattleibow

    Thanks, this solved my first issue. My app actually runs a little bit faster as well so that's an extra plus.

    I still need to figure out how to call a native method through a custom render.

  • RichardPresleyRichardPresley USMember ✭✭
    protected override void OnElementChanged(ElementChangedEventArgs<ImageWithTouch> e)
            {
                base.OnElementChanged(e);
    
                if (e.OldElement == null)
                {
                    SetNativeControl(new DrawView(Context,e.NewElement.CurrentStream));
                }
                //native method
                //Control.SaveImage();
                //      ||
                //  /\  \/
                //  ||
                //forms method
                //e.NewElement.Save();
    
            }
    
  • Hey @RichardPresley Nice work!!
    Did you improved it since last demo?

    Have you seen this project also?: https://github.com/pierceboggan/Moments

    It has some nice features that could help.

    If you have any improves on your sample, let me know!

    Thanks :smile:

  • Hey @RichardPresley Nice work!!
    Did you improved it since last demo?

    Have you seen this project also?: https://github.com/pierceboggan/Moments

    It has some nice features that could help.

    If you have any improves on your sample, let me know!

    Thanks :smile:

Sign In or Register to comment.