Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make any view to draw to canvas?

I have a short question:

Suppose I have a (mutable) bitmap that I need to modify (add images, texts, etc...) .

Instead of messing around with many special classes for drawing to the canvas (paint, canvas, matrices and so on), I was thinking why not use the built in classes of Android for this task and only if i need really customized operations i could still use the canvas ?

So, for example, in order to show any kind of view (that has no parent, of course) on the bitmap, I could call the next function :

public void drawViewToBitmap(Bitmap b, View v, Rect rect) {     Canvas c = new Canvas(b);     // <= use rect to let the view to draw only into this boundary inside the bitmap     view.draw(c); } 

Is such a thing possible? maybe that's even the way that it works behind the scenes?

what should i write in the part between the drawing and the creation of the canvas?


EDIT: i've tried the next code , but it didn't work:

public void drawFromViewToCanvas(final View view, final Rect rect, final Canvas canvas) {     final int widthSpec = View.MeasureSpec.makeMeasureSpec(rect.width(), View.MeasureSpec.EXACTLY);     final int heightSpec = View.MeasureSpec.makeMeasureSpec(rect.height(), View.MeasureSpec.EXACTLY);     view.measure(widthSpec, heightSpec);     // Lay the view out with the known dimensions     view.layout(0, 0, rect.width(), rect.height());     // Translate the canvas so the view is drawn at the proper coordinates     canvas.save();     canvas.translate(rect.left, rect.top);     // Draw the View and clear the translation     view.draw(canvas);     canvas.restore(); } 

example of usage:

final int imageSize = 50; rect = new Rect(35, 344 , 35 + imageSize, 344  + imageSize); final ImageView imageView = new ImageView(mContext); imageView.setImageBitmap(bitmap); imageView.setScaleType(ScaleType.CENTER_CROP); drawFromViewToCanvas(imageView, getRect(), canvas); 

EDIT: there is a sample on sony's website:

int measureWidth = View.MeasureSpec.makeMeasureSpec(bitmapWidth, View.MeasureSpec.EXACTLY); int measuredHeight = View.MeasureSpec.makeMeasureSpec(bitmapHeight, View.MeasureSpec.EXACTLY); view.measure(measureWidth, measuredHeight); view.layout(0, 0, bitmapWidth, bitmapHeight); view.draw(canvas); 

wonder if it works.

like image 810
android developer Avatar asked Jul 08 '13 16:07

android developer


People also ask

How do I add a view to Canvas?

This can be achieved simply by extending the View class and define an onDraw() callback method. Inside your View component's onDraw(), use the Canvas given to you for all your drawing, using various Canvas. draw... () methods (Ex: canvas.

What is the use of Canvas view?

Canvas has a method to draw a rectangle, while Paint defines whether to fill that rectangle with a color or leave it empty. Simply put, Canvas defines shapes that you can draw on the screen, while Paint defines the color, style, font, and so forth of each shape you draw.

How do you make a bitmap on Canvas?

Use the Canvas method public void drawBitmap (Bitmap bitmap, Rect src, RectF dst, Paint paint) . Set dst to the size of the rectangle you want the entire image to be scaled into. EDIT: Here's a possible implementation for drawing the bitmaps in squares across on the canvas.

What is the use of Canvas in android?

The Canvas class holds the "draw" calls. To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, Path, text, Bitmap), and a paint (to describe the colors and styles for the drawing).


1 Answers

Yeah, you can do this. Keep in mind, since you're not attaching it to a layout, you'll need to lay it out manually before drawing it:

view.layout(0, 0, viewWidth, viewHeight); 

And unless you just know exactly what you want for those width and height parameters, you may also want to measure it first:

int widthSpec = MeasureSpec.makeMeasureSpec (ViewGroup.LayoutParams.WRAP_CONTENT, MeasureSpec.UNSPECIFIED; int heightSpec = MeasureSpec.makeMeasureSpec (400, MeasureSpec.UNSPECIFIED; view.measure(widthSpec, heightSpec); view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); 

EDIT:

If you already know the width and height you need:

//Lay the view out with the known dimensions view.layout (0, 0, rect.width(), rect.height());  //Translate the canvas so the view is drawn at the proper coordinates canvas.save(); canvas.translate(rect.left, rect.top);  //Draw the View and clear the translation view.draw(canvas); canvas.restore(); 

EDIT again:

Yes, tested. You can try this yourself:

public class DrawingActivity extends Activity {     public void onCreate (Bundle savedInstanceState) {         super.onCreate(savedInstanceState);          //Set a Rect for the 200 x 200 px center of a 400 x 400 px area         Rect rect = new Rect();         rect.set(100, 100, 300, 300);          //Allocate a new Bitmap at 400 x 400 px         Bitmap bitmap = Bitmap.createBitmap(400, 400, Bitmap.Config.ARGB_8888);         Canvas canvas = new Canvas(bitmap);          //Make a new view and lay it out at the desired Rect dimensions         TextView view = new TextView(this);         view.setText("This is a custom drawn textview");         view.setBackgroundColor(Color.RED);         view.setGravity(Gravity.CENTER);          //Measure the view at the exact dimensions (otherwise the text won't center correctly)         int widthSpec = View.MeasureSpec.makeMeasureSpec(rect.width(), View.MeasureSpec.EXACTLY);         int heightSpec = View.MeasureSpec.makeMeasureSpec(rect.height(), View.MeasureSpec.EXACTLY);         view.measure(widthSpec, heightSpec);          //Lay the view out at the rect width and height         view.layout(0, 0, rect.width(), rect.height());          //Translate the Canvas into position and draw it         canvas.save();         canvas.translate(rect.left, rect.top);         view.draw(canvas);         canvas.restore();          //To make sure it works, set the bitmap to an ImageView         ImageView imageView = new ImageView(this);         imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));         setContentView(imageView);         imageView.setScaleType(ImageView.ScaleType.CENTER);         imageView.setImageBitmap(bitmap);     } } 
like image 185
Kevin Coppock Avatar answered Oct 14 '22 16:10

Kevin Coppock