What is the relationship between canvas and matrix in Android? - android

I read this canvas overview :
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).
Can anyone explain the canvas more clearly?
And I am confused about the relationship between the canvas and matrix. Does the canvas takes the transformations from the matrix?
And I want to know if below function affect on the canvas?
canvas.drawBitmap(bitmap, matrix, paint);
In other words, is the canvas matrix different from the bitmap matrix?
I asked this, because when I'm using canvas.drawBitmap and then using canvas.concat() and then drawing any object, this object takes same transformations on canvas, so I think the canvas and bitmap have the same matrix!!

They are different. When using the canvas to draw a bitmap providing a matrix, internally, the provided matrix are concatenated to the current canvas matrix.
In other words, calling canvas.drawBitmap(rectBitmap, matrix, paint); has the same effect of:
canvas.save();
canvas.concat(matrix);
canvas.drawBitmap(rectBitmap, 0, 0, paint);
canvas.restore();
This explain why your object is taking the same transformations because you are calling canvas.concat(matrix); and after that drawing the object.

Related

How to find center position of a bitmap that rotated and scaled with a matrix?

I want to calculate center of a bitmap that is drawn on a canvas with a matrix, it can be rotated, scaled or translated with a arbitrary value. What is the easiest way to find center of the this bitmap on canvas?
You need to apply the matrix to the coordinates of the center of bitmap.
If you use a canvas that has a transformation matrix, you can get the final matrix through Canvas.getMatrix()
If you draw the Bitmap on the Canvas with a Matrix : drawBitmap(bitmap, matrix, paint), then you you need to use that Matrix, or concatenate it to that of the Canvas (in the case it has one).
Then you can finally apply that matrix to the center of the matrix using Matrix.mapPoints.
Something like :
canvas.drawBitmap(bitmap, bitmap_transform, paint);
Matrix full_transform = new Matrix(canvas.getMatrix());
full_transform.postConcat(bitmap_transform);
float[] center = new float[] {bitmap.getHeight()/2.0, bitmap.getWidth()/2.0};
full_transform.mapPoints(center);
Alternatively, if you apply transformations to your bitmap without a matrix, you can use the full_transform.postRotate, full_transform.postScale, etc with the same values. In particular, if you draw your bitmap with drawBitmap(bitmap, left, top, paint) then you need to do a full_transform.postTranslate(left, top).
If you're looking for the "easiest" way then just sticking with the translate rotate and scale functions would solve the problem. The reason that those were developed was so developers wouldn't have to do vector calculus for simple animations. Also the only value you would have to actually calculate in that sense it is the translate value after you take into account the original coordinates.

How to copy one canvas into another canvas?

I have drawn some rects into a canvas and I want to copy those rects into another canvas.The commonly discussed solution of using bitmaps will not work because I didn't use a bitmap in this canvas, no images only those rects.
How do I do that?
Have you tried saving the attributes given to the rectangles upon drawing to the first canvas, and then redrawing them on the second canvas based on these attributes? Perhaps you could try creating a Rect-object for the first canvas and passing it to Canvas.drawRect() on the second canvas?
You can create a bitmap using a canvas and you draw on that bitmap.
bitmap = Bitmap.createBitmap(50,50,Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
// drawn some rects into canvas
Now you can use the bitmap to draw on any canvas you want;
Canvas canvas1 = new Canvas(bitmap);
Canvas canvas2 = new Canvas(bitmap);
Or if you have a canvas already:
canvas.drawBitmap(bitmap, 0, 0, paint);
This way you draw rects only once and not on each canvas.

Android - canvas drawing doubts

I am looking at one of the sample applications from Google, which deals with touch drawing using canvas:
http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.html
I have a few doubts:
I am not able to understand what's the role of Canvas versus the role
of the bitmap.
In the drawPoint function, I am not able to
understand this code snippet:
mCanvas.drawCircle(x, y, radius, mPaint);
mRect.set((int) (x - radius - 2), (int) (y - radius - 2),
(int) (x + radius + 2), (int) (y + radius + 2));
invalidate(mRect);
If the circle is already drawn into the canvas above, then what happens in the onDraw function where the following code is given:
canvas.drawBitmap(mBitmap, 0, 0, null);
Canvas vs Bitmap
A Bitmap is what the name suggests: A normal image as a bitmap. The Canvas class is an editor for bitmaps. You use it to change the bitmap data, it holds all drawing methods. This principle behaves similar to the shared preferences (if you already worked with them), you have a SharedPreferences class that holds the preferences, and an Editor class to change things.
Drawing the circles
This code does something similar to double buffering. drawPoint() basically draws a circle into the mBitmap object¹. But this bitmap object is not yet visible. It exists in the memory. When onDraw() is called, it has a Canvas argument that represents the drawing surface of the view. All that drawBitmap() does here is use the prepared bitmap from the memory and draw it inside the views graphical representation to make it visible.
¹ The used canvas mCanvas is tied to mBitmap inside onSizeChanged()
if you go to the developper refference:
drawBitmap(Bitmap bitmap, float left, float top, Paint paint)
Draw the
specified bitmap, with its top/left corner at (x,y), using the
specified paint, transformed by the current matrix.
Then if you see that mBitmap doesn't exist in the class , thats cause that var comes from the extend from another activity .
Canvas also has a setBitmap(Bitmap bitmap) function . Then the solution is that that paint in canvas if you have set into it a bitmap object.
From the Android SDK:
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).
I'm assuming you're referring to this snippet:
#Override protected void onDraw(Canvas canvas) {
if (mBitmap != null) {
canvas.drawBitmap(mBitmap, 0, 0, null);
}
}
Well it looks like an override of an inherited onDraw method which by default probably 'does nothing', hence the override to actually give it some behaviour, in this case given a non-null Bitmap instance, make the canvas draw it.

what is the relation between Canvas and Bitmap?

What is the relation between Canvas and Bitmap?
Bitmap drawingBitmap = Bitmap.createBitmap(bmp1.getWidth(),
bmp1.getHeight(), bmp1.getConfig());
canvas = new Canvas(drawingBitmap);
paint = new Paint();
canvas.drawBitmap(bmp1, 0, 0, paint);
paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.SCREEN));
canvas.drawBitmap(bmp2, 0, 0, paint);
compositeImageView.setImageBitmap(drawingBitmap);
I don't understand this code.Why the drawingBitmap is the composition of bmp1 and bmp2?
Basically, the Canvas is backed by a Bitmap, so when you draw anything using the canvas, the canvas will draw into the Bitmap it was created with. So, when you draw those two bitmaps using the canvas, it's going to composite the bitmaps together and the result will be stored in drawingBitmap, as it's backing the canvas.
Anh's analogy is correct-ish, though probably confusing (and over-simplifying, which I'm also doing above) – as I mentioned in a comment, you can think of the Canvas as the pen, the Paint as a configuration of that pen (e.g., replaceable ink or something - whatever you can fit into the idea of a configurable pen), and the Bitmap as the paper you draw onto. The analogy becomes confusing if you focus too much on the accepted meaning of the words.
Let's think canvas as a pen, and drawingBitmap as a paper. You use your pen to draw something on your paper, and you get what you draw.
Technically, you can construct Canvas object from Bitmap to draw others bitmaps on it.
Canvas is the place or medium where perfroms/executes the operation of drawing, and Bitmap is responsible for storing the pixel of the picture you draw.

Concepts about Android Drawable

How to get a well understanding the concept of the classes of Canvas,Drawable,Bitmap and Paint? What's the relationship among them ?
Could someone please give me an example?
Thanks a lot.
From the Canvas class documentation:
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).
So you need 4 components in order to draw something.
Bitmap
Canvas
Drawable
Paint
Let's say you want to draw a circle on a background image from your drawable folder.
Canvas canvas;
Bitmap mBG;
Paint mPaint = new mPaint();
mBG = BitmapFactory.decodeResource(res, R.drawable.apple); //Return a bitmap from the image from drawable folder
Canvas.drawBitmap(mBG, 0,0, null); //Draw the bitmap
mPaint.setColor(Color.BLACK); //Set paint to BLACK color
Canvas.drawCircle(100,100,30, mPaint); //Draw circle at coordinate x:100,y:100, radius 30 with the paint defined
Android's Official documentation covers all the details about the API. And best way to learn something is learn by doing, so after reading the docs, google for tutorials and experiment, all your doubts will be cleared gradually.
Canvas
Drawable
Bitmap
Paint

Categories

Resources