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.
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.
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.
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.
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).
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); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With