Android Adventures - Beginning Bitmap Graphics
Written by Mike James   
Monday, 27 July 2015
Article Index
Android Adventures - Beginning Bitmap Graphics
A First Graphic
Simple Animation
Timer and threads
Listing and Summary

A First Graphic

Now we have a Paint object we can draw a line:

c.drawLine(0F, 0F, 500F, 500F, paint);

This draws a line from 0,0 to 500,500 and as the Bitmap is 500 by 500 pixels this draws a diagonal line across the entire bitmap. Again the numeric values all end in F because the method needs float values - for reasons that will become clear later.

 

diag

 

 

All you have to do now is get to know the different drawing methods provided. Here are a few of the most common.

First we need to set the Paint object we created earlier to a FILL style so that we draw solid blocks of color and not just  outlines:

paint.setStyle(Paint.Style.FILL);

To draw a yellow circle all we need is:

paint.setColor(Color.YELLOW);
c.drawCircle(400F, 200F, 50F, paint);

The first two parameters give the position of the center and the third is the circle's radius. 

To draw a green rectangle:

paint.setColor(Color.GREEN);
c.drawRect(20F, 300F, 180F, 400F, paint);

The first two parameters give the top left hand corner and the next two the bottom right hand corner.

Finally some text:

paint.setColor(Color.BLACK);
paint.setTextSize(50F);
c.drawText("Hello Graphics",0,14,90,80,paint);

The Paint object has a number of properties that let you set the font and style. In this example we simply set the text size. The drawText method takes a string, the start and end positions of characters in the string that will be displayed and the coordinates of the starting location.

If you put this all together and run it you get the very tasteful graphic:

 

graphcshello

 

The complete code to create this is:

@Override
protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 Bitmap b = Bitmap.createBitmap(500, 500,
         Bitmap.Config.ARGB_8888);
 b.eraseColor(Color.RED);
 Canvas c = new Canvas(b);
 c = new Canvas(b);
 Paint paint = new Paint();
 paint.setAntiAlias(true);
 paint.setStrokeWidth(6f);
 paint.setColor(Color.BLUE);
 paint.setStyle(Paint.Style.STROKE);

 c.drawLine(0.0F, 0.0F, 500.0F, 500.0F, paint);
 paint.setStyle(Paint.Style.FILL);
 paint.setColor(Color.YELLOW);
 c.drawCircle(400F, 200F, 50F, paint);
 paint.setColor(Color.GREEN);
 c.drawRect(20F, 300F, 180F, 400F, paint);
 paint.setColor(Color.BLACK);
 paint.setTextSize(50F);
 c.drawText("Hello Graphics",0,14,90,80,paint);
 ImageView imageview=
      (ImageView) findViewById(R.id.imageView);
 imageview.setImageBitmap(b);
}

 

You can use this to try out other Canvas graphics methods.

If is worth pointing out that there is a set of drawBitmap methods that you can use to draw an existing Bitmap onto the Bitmap associated with the Canvas. This might seem like a strange thing to do but it is one of the most useful drawing operations because you can us it to implement simple sprite animation.  

Transformations

Now we come to one of the more sophisticated options that Canvas offers. Before anything is drawn the coordinates you supply are acted on by a transformation matrix. By default this is set to the identity matrix which leaves the coordinates as they were. However there are a range of transformation methods which modify the transformation matrix:

  • rotate(float degrees) rotate about the origin through degrees
  • rotate(float degrees, float px, float py) rotate about the point px,py through degrees
  • scale(float sx, float sy) scale about the origin by sx and sy
  • scale(float sx, float sy, float px, float py) scale about the point px,py by sx and sy
  • skew(float sx, float sy) skew by sx and sy
  • translate(float dx, float dy) translate by dx and dy.

There are also some methods that let you work directly with the transformation matrix:

  • setMatrix(Matrix matrix) set the transform to the matrix provided
  • concat(Matrix matrix)  multiply the transform matrix by the matrix provided.
  • getMatrix(Matrix ctm) get the transformation matrix in ctm
  • getMatrix() return a copy of the transformation matrix

If you know how matrices and transformation matrices work then this will be nothing new to you.

If you don't know about transformations and matrices then there are a lot of traps waiting to trip you up. The main one that gets just about everyone at first is that the order in which you do things matter. A translation followed by a rotation isn't the same thing as a rotation followed by a translation. Try it if you don't believe me.

Another one is that these transformations change the coordinate system and don't affect anything you have already drawn. They only change what happens when you draw something after the transformation has been applied. 

For example:

paint.setColor(Color.GREEN);
c.drawRect(20F, 300F, 180F, 400F, paint);
c.rotate(15F);
paint.setColor(Color.BLACK);
paint.setTextSize(50F);
c.drawText("Hello Graphics",0,14,90,80,paint);

In this case there is a 15 degree rotation after the rectangle has been drawn and before the text is drawn. The result is that the rectangle stays where it was but the text is rotated. 

 

rotate

 

After the rotation everything you draw will be at 15 degrees. 

Notice that the rotation is about the origin i.e. 0,0 the top left hand corner. If you want to rotate about a different point, usually the center of some object you need to use rotate(d,x,y). For example to rotate the rectangle about it's center you would use:

paint.setColor(Color.GREEN);
c.rotate(45,100,350);
c.drawRect(20F, 300F, 180F, 400F, paint);

where 100,350 is the center of the rectangle:

 

rotate2

 

You can also see that the text is now in a different position and not simply rotated about the origin. This is because the 15 degree rotation is added to the 45 degree rotation around the center of the rectangle. To keep your transformations separate and non-interacting you have to remember to return the transformation matrix to the identity after you have changed it to something else. 

How do you set the matrix back to the identity?

You could use

c.setMatrix(new Matrix());

as Matrix() creates an identity matrix by default or you could just use

c.setMatrix(Null);

because passing a Null causes the matrix to be reset. 

However, needing to make a change to the transformation matrix and then restore the original is such a common operation that Canvas supports:

c.save()

which saves the current matrix and

c.restore() 

which restores the current matrix. 

For example:

paint.setColor(Color.GREEN);
c.save();

c.rotate(45, 100, 350);

c.drawRect(20F, 300F, 180F, 400F, paint);

c.restore();

c.rotate(15F);

paint.setColor(Color.BLACK);

paint.setTextSize(50F);
c.drawText("Hello Graphics",0,14,90,80,paint);

With the save before the first rotate, the restore before the second decouples the two transformations.



Last Updated ( Wednesday, 12 October 2016 )