0

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!

XTL
  • 1,452
  • 2
  • 17
  • 40
  • If I understand what you're trying to achieve, in the `DrawBitmap()` method, you want to keep the null source `Rect`, and change the destination `Rect` to `new Rect(3 * bt.Width / 4, 3 * bt.Height / 4, bt.Width, bt.Height)`. – Mike M. Dec 09 '15 at 16:43
  • @MikeM. thanks for the reply!! No,no...its just was for example. I need to do with Source Rect area..this behaviour is strange :( – XTL Dec 09 '15 at 19:40
  • Then I don't understand your question. The image you've shown is exactly how your second `DrawBitmap()` example should behave. You're telling it to take the right-half of the image, and draw it into the lower-right quarter of the image. – Mike M. Dec 09 '15 at 19:54
  • @MikeM. on both examples,you can see,that area of bitmap,that is drawn is duplicated(why this happens) ? – XTL Dec 09 '15 at 19:59
  • Oh, OK, I think I get ya now. I thought you'd just omitted some `DrawBitmap()` calls in your example code. But you mean that that's your whole code, and you're getting those weird echo images. – Mike M. Dec 09 '15 at 20:02
  • @MikeM. excatly...ECHO images...why this happens!? – XTL Dec 09 '15 at 20:03
  • Hang on. I'm gonna see if I can reproduce this. – Mike M. Dec 09 '15 at 20:08
  • @MikeM. okay,ill wait:). Thanks! – XTL Dec 09 '15 at 20:09
  • Yeah, the issue is that you're drawing `bt` onto itself, which is causing it to recursively draw until it hits a lower size limit on the `Rect`. It'll take a little reworking of your code, but you'll need to create another `Bitmap` and `Canvas` to do your drawing on, then set that `Bitmap` on the destination `ImageView`. [Here's a screenshot of the result.](http://i.imgur.com/yLtEWFN.png) – Mike M. Dec 09 '15 at 20:51
  • @MikeM. hey,can you see also this question http://stackoverflow.com/questions/34062615/how-to-get-correct-coordsevent-getx-event-gety-of-object-with-ontouchlis thanks! – XTL Dec 10 '15 at 08:48

1 Answers1

1

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.

Mike M.
  • 38,532
  • 8
  • 99
  • 95
  • Dude,you're right! The problem that i used same bitmap :). Thanks! – XTL Dec 09 '15 at 22:00
  • No problem. I didn't realize it myself until I was translating your example to Java. Glad it worked for ya. Cheers! – Mike M. Dec 09 '15 at 22:01