Search code examples
androidcanvasbitmapxamarindrawbitmap

Canvas.DrawBitmap unexpected result(BUG or strange behaviour) Xamarin Android


So i have an problem with method of Canvas.DrawBitmap(), that draws unexpected result.
Lets see my example:
Source image
image


I have two cases(just for test):

  1. I want to draw Red rectangle from 0,0 and give for him size 1/4 of image,also i want to draw this bitmap in same size(1/4) and put to Bottom.Right place.
  2. Draw again Red rectangle with same conditions(starts from Top.Left(0,0) and size 1/4 of image) and draw part of bitmap and shows as Rectangle with 1/4 size(Bottom.Right).

Case #1

i'm doing this:

//source imageview
Source.SetImageResource(Resource.Drawable.lena30);
//bitmap
            bt = ((BitmapDrawable)Source.Drawable).Bitmap.Copy(Bitmap.Config.Argb8888, true); 
//second imageview, where i fill result
            Draw.SetImageBitmap(bt);
            can = new Canvas(bt);

                Paint paint = new Paint();
                paint.Color = Color.Red;
                paint.SetStyle(Paint.Style.Fill);
                //draw Red Rect with 1/4 size and locate Top.Left
                can.DrawRect(0,0,bt.Width/2,bt.Height/2,paint);
                //redraw new bitmap(all subset) and locate to Bottom.Right with 1/4 size
                can.DrawBitmap(bt, null, new Rect(bt.Width/2, bt.Height / 2, bt.Width, bt.Height), null);  

and the result is :
result case1


Case #2

same,but getting now part of bitmap(not full subset of bitmap):

 //source imageview
    Source.SetImageResource(Resource.Drawable.lena30);
    //bitmap
                bt = ((BitmapDrawable)Source.Drawable).Bitmap.Copy(Bitmap.Config.Argb8888, true); 
    //second imageview, where i fill result
                Draw.SetImageBitmap(bt);
                can = new Canvas(bt);

                    Paint paint = new Paint();
                    paint.Color = Color.Red;
                    paint.SetStyle(Paint.Style.Fill);
                    //draw Red Rect with 1/4 size and locate Top.Left
                    can.DrawRect(0,0,bt.Width/2,bt.Height/2,paint);
                    //redraw new bitmap(not full,only part of Source Rectangle) and locate to Bottom.Right with 1/4 size
                    can.DrawBitmap(bt, new Rect(bt.Width/2,0,bt.Width,bt.Height), new Rect(bt.Width/2, bt.Height / 2, bt.Width, bt.Height), null);  

result case2


So i cant understand,why that happens?(Why image no scaling to fit size and duplicate Rectangles!?).
Any ideas? Thanks!


Solution

  • The issue is that you're drawing the bt Bitmap onto itself, which is causing it to recursively draw until it hits a minimum size limit. It'll take a little reworking of your code, but you'll need to create an intermediate Bitmap and Canvas on which to do your drawing, then set that Bitmap on the target ImageView.

    Source.SetImageResource(Resource.Drawable.lena30);
    
    bt = ((BitmapDrawable) Source.Drawable).Bitmap.Copy(Bitmap.Config.Argb8888, true); 
    
    Paint paint = new Paint();
    paint.Color = Color.Red;
    paint.SetStyle(Paint.Style.Fill);
    
    Canvas canSource = new Canvas(bt);
    canSource.DrawRect(0, 0, bt.Width / 2, bt.Height / 2, paint);
    
    Bitmap btDraw = Bitmap.CreateBitmap(bt.Width, bt.Height, Bitmap.Config.Argb8888);   
    Canvas canDraw = new Canvas(btDraw);
    
    canDraw.DrawBitmap(bt, null, new Rect(0, 0, bt.Width, bt.Height), null);
    canDraw.DrawBitmap(bt, null, new Rect(bt.Width / 2, bt.Height / 2, bt.Width, bt.Height), null);
    
    Draw.SetImageBitmap(btDraw);
    

    NB: I've never used Xamarin, so please forgive any syntax errors in my attempted translation.