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.
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);
}
}