How to Draw Graphics on Android Canvas in Android Studio (2021)

This entire tutorial will be about the Android Canvas class and some related classes, including PaintColor, and Bitmap. These classes combined bring great power when it comes to drawing to the screen. Sometimes the default UI provided by the Android API isn’t what we need. If we want to make a drawing app, draw graphs, or perhaps create a game, we need to take control of every pixel that the Android device has to offer.

In this tutorial, we will cover the following:

  • Understanding Canvas and related classes
  • Writing a Canvas-based demo app
  • Looking at the Android coordinate system so we know where to do our drawing
  • Learning about drawing and manipulating bitmaps
  • Writing a bitmap-based demo app

Let’s draw!

Understanding the Android Canvas class

The Canvas class is part of the android.graphics package. We will be using all the following import statements from the android.graphics package and one more from the now-familiar View package. They give us access to some powerful drawing methods from the Android API:

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.widget.ImageView;

First, let’s talk about BitmapCanvas, and ImageView, as highlighted in the previous code.

Getting started drawing with Bitmap, Canvas, and ImageView

As Android is designed to run all types of mobile apps, we can’t immediately start typing our drawing code and expect it to work. We need to do a bit of preparation (coding) to consider the specific device our app is running on. It is true that some of this preparation can be slightly counterintuitive, but we will go through it a step at a time.

CANVAS AND BITMAP

Depending on how you use the Canvas class, the term can be slightly misleading. While the Canvas class is the class to which you draw your graphics, like a painting canvas, you still need a surface to transpose the canvas.

The surface, in this case (and in our first two demo apps), will be from the Bitmap class. We can think of it like this: we get a Canvas object and a Bitmap object and then set the Bitmap object as the part of the Canvas object to draw upon.

This is slightly counterintuitive if you take the word canvas in its literal sense but once it is all set up, we can forget about it and concentrate on the graphics we want to draw.

NOTE

The Canvas class supplies the ability to draw. It has all the methods for doing things such as drawing shapes, text, lines, and image files (including other bitmaps), and even plotting individual pixels.

The Bitmap class is used by the Canvas class and is the surface that gets drawn upon. You can think of the Bitmap instance as being inside a picture frame on the Canvas instance.

PAINT

In addition to the Canvas and Bitmap classes, we will be using the Paint class. This is much more easily understood. Paint is the class used to configure specific properties such as the color that we will draw on Bitmap (within Canvas).

There is still another piece of the puzzle to cover before we can start drawing.

IMAGEVIEW AND ACTIVITY

The ImageView class is the class that the Activity class will use to display output to the user. The reason for this third layer of abstraction is that as we have seen throughout the book, the Activity class needs to pass a View to the setContentView method to display something to the user. Throughout the book so far, this has been a layout that we created in the visual designer or in XML code.

This time, we don’t want a regular UI; we want to draw lines, pixels, and shapes.

There are multiple types of classes that extend the View class, enabling many different types of apps to be made, and they will all be compatible with the Activity class, which is the foundation of all regular Android apps (including drawing apps and games).

It is, therefore, necessary to associate the Bitmap class that gets drawn on (through its association with Canvas) with ImageView, once the drawing is done. The last step will be telling Activity that our ImageView class represents the content for the user to see by passing it to the setContentView method.

CANVAS, BITMAP, PAINT, AND IMAGEVIEW QUICK SUMMARY

If the theory of the code structure we need to set up seems like it is not simple, you will breathe a sigh of relief when you see the relatively simple code shortly.

A quick summary of what we know so far:

  • Every app needs an Activity class to interact with the user and the underlying operating system. Therefore, we must conform to the required hierarchy if we want to succeed.
  • We will use the ImageView class, which is a type of the View class. The View class is what Activity needs to display our app to the user.
  • The Canvas class supplies the ability to draw lines, pixels, and other graphics too. It has all the methods for doing things such as drawing shapes, text, lines, and image files, and even plotting individual pixels.
  • The Bitmap class will be associated with the Canvas class and it is the surface that actually gets drawn upon.
  • The Canvas class uses the Paint class to configure details such as the color.

Finally, once the bitmap has been drawn upon, we must associate it with the ImageView instance, which in turn is set as the view for Activity via the setContentView method.

The result will be what we draw on the Bitmap instance in the Canvas instance, which is displayed to the user through the ImageView instance via the call to the setContentView method. Phew!

NOTE

It doesn’t matter if that isn’t 100% clear. It is not that you aren’t seeing things clearly – it simply isn’t a clear relationship. Writing the code and using the techniques over and over will cause things to become clearer.

Let’s look at how to set up this relationship in code. Don’t worry about typing the code; just study it first.

Using the Canvas class

Let’s look at the code and the different stages required to get drawing, and then we can quickly move on to drawing something for real, with the Canvas demo app.

Preparing the instances of the required classes

The first step is to declare the instances of the classes we require:

// Here are all the objects(instances)

// of classes that we need to do some drawing

ImageView myImageView;

Bitmap myBlankBitmap;

Canvas myCanvas;

Paint myPaint;

The previous code declares references of the ImageViewBitmapCanvas, and Paint types. They are named myImageViewmyBlankBitmapmyCanvas, and myPaint, respectively.

Initializing the objects

Next, we need to initialize our new objects before using them:

// Initialize all the objects ready for drawing

// We will do this inside the onCreate method

int widthInPixels = 800;

int heightInPixels = 800;

myBlankBitmap = Bitmap.createBitmap(widthInPixels,

         heightInPixels,

         Bitmap.Config.ARGB_8888);

myCanvas = new Canvas(myBlankBitmap);

myImageView = new ImageView(this);

myPaint = new Paint();

// Do drawing here

Notice this comment in the previous code:

// Do drawing here

This is where we would configure our color and draw stuff. Also, notice at the top of the code we declare and initialize two int variables called widthInPixels and heightInPixels. When we code the Canvas demo app, I will go into greater detail about some of those lines of code.

We are now ready to draw. All we must do is assign the ImageView instance to Activity.

Setting the Activity content

Finally, before we can see our drawing, we tell Android to use our ImageView instance called myImageView as the content to display to the user:

// Associate the drawn upon Bitmap with the ImageView

myImageView.setImageBitmap(myBlankBitmap);

// Tell Android to set our drawing

// as the view for this app

// via the ImageView

setContentView(myImageView);

As we have already seen in every app so far, the setContentView method is part of the Activity class and we pass in myImageView as an argument, instead of an XML layout as we have been doing throughout the book so far. That’s it. All we must learn now is how to actually draw on that Bitmap instance.

Before we do some drawing, I thought it would be useful to start a real project, copy and paste the code we have just discussed, a step at a time, into the correct place, and then actually see something drawn to the screen.

Let’s do some drawing.

Android Canvas demo app

We will create a new project just to explore the topic of drawing with Canvas. We will reuse what we have just learned and this time, we will also draw to the Bitmap instance.

Creating a new project

Create a new project and call it Canvas Demo. Choose the Empty Activity template.

In addition, we are going to be using the vanilla version of the Activity class and the MainActivity class will therefore extend Activity instead of AppCompatActivity as we have been using previously. This is simply because we no longer need the extra features provided by the AppCompatActivity class.

The complete code for this app

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.widget.ImageView;

public class MainActivity extends Activity {

    // Here are all the objects(instances)
    // of classes that we need to do some drawing
    ImageView myImageView;
    Bitmap myBlankBitmap;
    Canvas myCanvas;
    Paint myPaint;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Initialize all the objects ready for drawing
        // We will do this inside the onCreate method
        int widthInPixels = 800;
        int heightInPixels = 600;

        // Create a new Bitmap
        myBlankBitmap = Bitmap.createBitmap(widthInPixels,
                heightInPixels,
                Bitmap.Config.ARGB_8888);

        // Initialize the Canvas and associate it
        // with the Bitmap to draw on
        myCanvas = new Canvas(myBlankBitmap);

        // Initialize the ImageView and the Paint
        myImageView = new ImageView(this);
        myPaint = new Paint();

        // Draw on the Bitmap
        // Wipe the Bitmap with a blue color
        myCanvas.drawColor(Color.argb(255, 0, 0, 255));

        // Re-size the text
        myPaint.setTextSize(100);
        // Change the paint to white
        myPaint.setColor(Color.argb(255, 255, 255, 255));
        // Draw some text
        myCanvas.drawText("Hello World!",100, 100, myPaint);

        // Change the paint to yellow
        myPaint.setColor(Color.argb(255, 212, 207, 62));
        // Draw a circle
        myCanvas.drawCircle(400,250, 100, myPaint);
        // Associate the drawn upon Bitmap with the ImageView
        myImageView.setImageBitmap(myBlankBitmap);
        // Tell Android to set our drawing
        // as the view for this app
        // via the ImageView
        setContentView(myImageView);

    }
}

CODING THE ANDROID CANVAS DEMO APP IN ANDROID STUDIO

To get started, edit the code in MainActivity.java, including adding the import directives and changing the version of the Activity class that the MainActivity class inherits from. Also notice in the next code that the call to the setContentView method has also been deleted. We will replace it soon:

import android.app.Activity;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.os.Bundle;

import android.widget.ImageView;

public class MainActivity extends Activity {

    // Here are all the objects(instances)

    // of classes that we need to do some drawing

    ImageView myImageView;

    Bitmap myBlankBitmap;

    Canvas myCanvas;

    Paint myPaint;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

    }

}

Now that we have declared instances of the required classes, we can initialize them. Add the following code to the onCreate method after the call to super.onCreate…, as shown in this next code:

@Override

protected void onCreate(Bundle savedInstanceState) {

   super.onCreate(savedInstanceState);

   // Initialize all the objects ready for drawing

   // We will do this inside the onCreate method

   int widthInPixels = 800;

   int heightInPixels = 600;

   // Create a new Bitmap

   myBlankBitmap = Bitmap.createBitmap(widthInPixels,

                heightInPixels,

                Bitmap.Config.ARGB_8888);

   // Initialize the Canvas and associate it

   // with the Bitmap to draw on

   myCanvas = new Canvas(myBlankBitmap);

   // Initialize the ImageView and the Paint

   myImageView = new ImageView(this);

   myPaint = new Paint();

}

This code is the same as we saw when we were discussing Canvas earlier. It is worth exploring the Bitmap class initialization as it is not straightforward.

Exploring the Bitmap initialization

Bitmaps, more typically in graphics-based apps and games, are used to represent objects such as different brushes to paint with, the player, backgrounds, game objects, and so on. Here we are simply using it to draw upon. In the next project, we will use bitmaps to represent the subject of our drawing, not just the surface to draw upon.

The method that needs explaining is the createBitmap method. The parameters from left to right are as follows:

  • The width (in pixels)
  • The height (in pixels)
  • The bitmap configuration

Bitmaps can be configured in several different ways. The ARGB_8888 configuration means that each pixel is represented by 4 bytes of memory.

There are a few bitmap formats that Android can use. This one is perfect for a good range of colors and will ensure that the bitmaps we use and the colors we request will be drawn as intended. There are higher and lower configurations but ARGB_8888 is perfect for the entirety of this tutorial.

Now we can do the actual drawing.

DRAWING ON THE SCREEN

Add this next highlighted code after the initialization of myPaint and inside the closing curly brace of the onCreate method:

myPaint = new Paint();

   // Draw on the Bitmap

   // Wipe the Bitmap with a blue color

   myCanvas.drawColor(Color.argb(255, 0, 0, 255));

   // Re-size the text

   myPaint.setTextSize(100);

   // Change the paint to white

   myPaint.setColor(Color.argb(255, 255, 255, 255));

   // Draw some text

   myCanvas.drawText("Hello World!",100, 100, myPaint);

   // Change the paint to yellow

   myPaint.setColor(Color.argb(255, 212, 207, 62));

   // Draw a circle

   myCanvas.drawCircle(400,250, 100, myPaint);

}

The previous code uses the myCanvas.drawColor method to fill the screen with color.

The myPaint.setTextSize method defines the size of the text that will be drawn next. The myPaint.setColor method determines what color any future drawing will be. The myCanvas.drawText method actually draws the text to the screen.

Analyze the arguments passed into the drawText method and we can see that the text will say “Hello World!” and will be drawn 100 pixels from the left and 100 pixels from the top of our bitmap (myBitmap).

Next, we use the setColor method again to change the color that will be used for drawing. Finally, we use the drawCircle method to draw a circle that is 400 pixels from the left and 100 pixels from the top. The circle will have a radius of 100 pixels.

I reserved explaining the Color.argb method until now.

Explaining Color.argb

The Color class, unsurprisingly, helps us to manipulate and represent color. The argb method used previously returns a color constructed using the alpha (opacity/transparency), red, green, blue (argb) model. This model uses values ranging from 0 (no color) to 255 (full color) for each element. It is important to note, although on reflection it might seem obvious, that the colors mixed are intensities of light and are quite different to what happens when we mix paint, for example.

NOTE

To devise an argb value and explore this model further, look at this handy website: https://www.rapidtables.com/web/color/RGB_Color.html. The site helps you pick the RGB values; you can then experiment with the alpha values.

The values used to clear the drawing surface were 255, 0, 0, 255. These values mean full opacity (solid color), no red, no green, and full blue. This makes a blue color.

The next call to the argb method is in the first call to setColor where we are setting the required color for the text. The values 255, 255, 255, 255 mean full opacity, full red, full green, and full blue. When you combine light with these values, you get white.

The final call to the argb method is in the final call to the setColor method when we are setting the color to draw the circle. 255, 21, 207, 62 makes a sun-yellow color.

The last step before we can run the code is to add the call to the setContentView method that places our ImageView (myImageView) as the View instance to be set as the content for this app. Here are the final lines of code to be added before the closing curly brace of the onCreate method:

// Associate the drawn upon Bitmap with the ImageView

myImageView.setImageBitmap(myBlankBitmap);

// Tell Android to set our drawing

// as the view for this app

// via the ImageView

setContentView(myImageView);

Finally, we tell the Activity class to use myImageView by calling the setContentView method.

This is what the Canvas demo looks like when you run it. We can see an 800 by 800-pixel drawing:

Figure 20.1 – Canvas demo

Figure 20.1 – Canvas demo

It will help to understand the result of the coordinates we use in our Canvas class drawing methods if we better understand the Android coordinate system.

The Android coordinate system

As we can see, drawing a bitmap is trivial. But the coordinate system that we use to draw our graphics onto needs a brief explanation.

Plotting and drawing

When we draw a Bitmap object to the screen, we pass in the coordinates we want to draw the object at. The available coordinates of a given Android device depend upon the resolution of its screen.

For example, the Google Pixel phone has a screen resolution of 1,920 pixels (across) by 1,080 pixels (down) when held in landscape view.

The numbering system of these coordinates starts in the top left-hand corner at 0, 0 and proceeds down and to the right until the bottom-right corner, which is pixel 1919, 1079. The apparent 1-pixel disparity between 1920 and 1919 and 1080 and 1079 is because the numbering starts at 0.

So, when we draw a bitmap or anything else to the screen (such as Canvas circles and rectangles), we must specify an x, y coordinate.

Furthermore, a bitmap (or Canvas shape) of course comprises many pixels. So, which pixel of a given bitmap is drawn at the x, y screen coordinate that we will be specifying?

The answer is the top-left pixel of the Bitmap object. Look at the next figure, which should clarify the screen coordinates using the Google Pixel phone as an example. As a graphical means for explaining the Android coordinate drawing system, I will use a cute spaceship graphic:

Figure 20.2 – Screen coordinates

Figure 20.2 – Screen coordinates

Furthermore, the coordinates are relative to what you draw upon. So, in the Canvas demo app we just coded, as well as the next demo, the coordinates are relative to the bitmap (myBitmap).

Let’s do some more drawing, this time with bitmaps from a graphics file. We will use the same starting code as we have seen in this app.

Creating bitmaps

Let’s do a little bit of theory before we dive into the code and consider exactly how we are going to bring images to life on the screen. To draw a bitmap, we will use the drawBitmap method of the Canvas class.

First, we would need to add a bitmap to the project in the res/drawable folder; we will do this for real in the Bitmap demo app coming up shortly. For now, assume the graphics file/bitmap has the name myImage.png.

Next, we declare an object of the Bitmap type, just the same as we did for the Bitmap object we used for our background in the previous demo:

Bitmap mBitmap;

Next, we need to initialize the mBitmap object using our preferred image that we previously added to the project’s drawable folder:

mBitmap = BitmapFactory.decodeResource

                (getResources(), R.drawable.myImage);

The static decodeResource method of the BitmapFactory method is used to initialize mBitmap. It takes two parameters. The first is a call to getResources, which is made available by the Activity class. This method, as the name suggests, gives access to the project resources, and the second parameter, R.drawable.myImage, points to the myImage.png file in the drawable folder. The bitmap (mBitmap) is now ready to be drawn by the Canvas class.

You could then draw the bitmap with the following code:

// Draw the bitmap at coordinates 100, 100

mCanvas.drawBitmap(mBitmap,

                100, 100, mPaint);

Here is what the spaceship graphic from the previous section looks like when drawn to the screen as a reference for when we talk about rotating bitmaps:

Figure 20.3 – Spaceship graphic

Figure 20.3 – Spaceship graphic

Manipulating bitmaps

Quite often, however, we need to draw bitmaps in a rotated or otherwise altered state. It would be quite easy to use Photoshop or whatever your favorite image editing software happens to be to create more bitmaps from the original bitmap to face in other directions. Then, when we come to draw our bitmap, we can simply decide which way to face and draw the appropriate pre-loaded bitmap.

However, I thought it would be much more interesting and instructive if we worked with just one single source image and learned about the class that Android provides to manipulate images in our Java code. You will then be able to add rotating and inverting graphics to your app developer’s toolkit.

What is a bitmap exactly?

A bitmap is called a bitmap because that is exactly what it is: a map of bits. While there are many bitmap formats that use different ranges and values to represent colors and transparency, they all amount to the same thing. They are a grid/map of values and each value represents the color of a single pixel.

Therefore, to rotate, scale, or invert a bitmap, we must perform the appropriate mathematical calculation upon each pixel/bit of the image/grid/map of the bitmap. The calculations are not terribly complicated, but they are not especially simple either. If you took math to the end of high school, you will probably understand the math without too much bother.

Unfortunately, understanding the math isn’t enough. We would also need to devise efficient code, as well as understanding the bitmap format, and then modify our code for each format. This would not be trivial. Fortunately, the Android API has done it all for us. Meet the Matrix class.

The Matrix class

The class is named Matrix because it uses the mathematical concept and rules to perform calculations on a series of values known as matrices – the plural of the matrix.

NOTE

The Android Matrix class has nothing to do with the movie series of the same name. However, the author advises that all aspiring app developers take the red pill.

You might be familiar with matrices but don’t worry if you’re not because the Matrix class hides all the complexity away. Furthermore, the Matrix class not only allows us to perform calculations on a series of values, but it also has some pre-prepared calculations that enable us to do things such as rotating a point around another point by a specific number of degrees. All this without knowing anything about trigonometry.

This tutorial will stick to using the Android Matrix class.

INVERTING A BITMAP TO FACE THE OPPOSITE DIRECTION

First, we need to create an instance of the Matrix class. This next line of code does so in a familiar way by calling new on the default constructor:

Matrix matrix = new Matrix();

NOTE

Note that you don’t need to add any of this code to a project right now; it will all be shown again shortly with much more context. I just thought it would be easier to see all the Matrix-related code on its own beforehand.

Now we can use one of the many neat methods of the Matrix class. The preScale method takes two parameters: one for the horizontal change and one for the vertical change. Look at this line of code:

matrix.preScale(-1, 1);

What the preScale method will do is loop through every pixel position and multiply all the horizontal coordinates by -1 and all the vertical coordinates by 1.

The effect of these calculations is that all the vertical coordinates will remain the same because if you multiply by 1, then the number doesn’t change. However, when you multiply by -1, the horizontal position of the pixel will be inverted. Take the following example:

Horizontal positions 0, 1, 2, 3, and 4 will become 0, -1, -2, -3, and -4.

At this stage, we have created a matrix that can perform the necessary calculations on a bitmap. We haven’t actually done anything with the bitmap yet. To use the matrix, we call the createBitmap method of the Bitmap class such as this line of code shown next:

mBitmapLeft = Bitmap

.createBitmap(mBitmap,

          0, 0, 25, 25, matrix, true);

The previous code assumes that mBitmapLeft is already initialized as well as mBitmap. The parameters of the createBitmap method are explained as follows:

  • mBitmapHeadRight is a Bitmap object that has already been created and scaled and has the image of a spaceship (facing the right) loaded into it. This is the image that will be used as the source for creating the new bitmap. The source bitmap will not actually be altered at all.
  • 0, 0 is the horizontal and vertical starting position that we want the new bitmap to be mapped into.
  • The 25, 25 parameters are values that set the size that the bitmap is scaled to.
  • The next parameter is our pre-prepared Matrix instance, matrix.
  • The final parameter, true, instructs the createBitmap method that filtering is required to correctly handle the creation of the bitmap.

This is what mBitmapLeft will look like when drawn to the screen:

Figure 20.4 – mBitmapLeft

Figure 20.4 – mBitmapLeft

We can also create the bitmap facing up or down using a rotation matrix.

ROTATING THE BITMAP TO FACE UP OR DOWN

Let’s look at rotating a bitmap, and then we can build the demo app. We already have an instance of the Matrix class, so all we must do is call the preRotate method to create a matrix capable of rotating every pixel by a specified number of degrees in the single argument to preRotate. Look at this line of code:

// A matrix for rotating

matrix.preRotate(-90);

How simple was that? The matrix instance is now ready to rotate any series of numbers we pass to it, anti-clockwise (), by 90 degrees.

This next line of code has exactly the same parameters as the previous call to createBitmap that we previously dissected, except that the new Bitmap instance is assigned to mBitmapUp and the effect of matrix is to perform the rotation instead of preScale:

mBitmapUp = Bitmap

.createBitmap(mBitmap,

         0, 0, ss, ss, matrix, true);

This is what mBitmapUp will look like when drawn:

Figure 20.5 – mBitmapUp

Figure 20.5 – mBitmapUp

You can also use the same technique but a different value in the argument to preRotate to turn the bitmap downward. Let’s get on with the demo app to see all this stuff in action.

Bitmap manipulation demo app

Now that we have studied the theory, let’s draw and spin some bitmaps. Create a new project using the Empty Activity template and call it Manipulating Bitmaps.

Adding the graphic to the project

Save the image given below and name it bob.png

bob.png

Right-click and select Copy to copy the bob.png graphics file.

In Android Studio, locate the app/res/drawable folder in the project explorer window. This next screenshot makes clear where this folder can be located and what it will look like with the bob.png image in it:

Figure 20.6 – app/res/drawable folder with bob.png

Figure 20.6 – app/res/drawable folder with bob.png

Right-click on the drawable folder and select Paste to add the bob.png file to the project. Click OK twice to confirm the default options for importing the file into the project.

Edit the code of the MainActivity class to include all the required import directives, the basic version of the Activity class, and a selection of member variables so we can get started. The state of the MainActivity class at this stage is shown next:

import android.app.Activity;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.os.Bundle;

import android.widget.ImageView;

import android.graphics.BitmapFactory;

import android.graphics.Color;

import android.graphics.Matrix;

public class MainActivity extends Activity {

    // Here are all the objects(instances)

    // of classes that we need to do some drawing

    ImageView myImageView;

    Bitmap myBlankBitmap;

    Bitmap bobBitmap;

    Canvas myCanvas;

    Paint myPaint;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        

    }

}

Now we can initialize all the members in onCreate:

// Initialize all the objects ready for drawing

int widthInPixels = 2000;

int heightInPixels = 1000;

// Create a new Bitmap

myBlankBitmap = Bitmap.createBitmap(widthInPixels,

         heightInPixels,

         Bitmap.Config.ARGB_8888);

// Initialize Bob

bobBitmap = BitmapFactory.decodeResource

         (getResources(), R.drawable.bob);

// Initialize the Canvas and associate it

// with the Bitmap to draw on

myCanvas = new Canvas(myBlankBitmap);

// Initialize the ImageView and the Paint

myImageView = new ImageView(this);

myPaint = new Paint();

// Draw on the Bitmap

// Wipe the Bitmap with a blue color

myCanvas.drawColor(Color.argb(255, 0, 0, 255));

Next, we add calls to three methods that we will write soon and set our new drawing as the view for the app:

void drawRotatedBitmaps(){

   float rotation = 0f;

   int horizontalPosition =350;

   int verticalPosition = 25;

   Matrix matrix = new Matrix();

   Bitmap rotatedBitmap = Bitmap.createBitmap(100,

                200,

                Bitmap.Config.ARGB_8888);

   for(rotation = 0; rotation < 360; rotation += 30){

         matrix.reset();

         matrix.preRotate(rotation);

         rotatedBitmap = Bitmap

                      .createBitmap(bobBitmap,

                                  0, 0, bobBitmap

                                  .getWidth()-1,

                                  bobBitmap.getHeight()-1,

                                  matrix, true);

         myCanvas.drawBitmap(rotatedBitmap,

                      horizontalPosition,

                      verticalPosition,  

                      myPaint);

         

         horizontalPosition += 120;

         verticalPosition += 70;

   }

}

The previous code uses a for loop to loop through 360 degrees 30 degrees at a time. The value that each pass through the loop is used in the Matrix instance to rotate the image of Bob, and he is then drawn to the screen using the drawBitmap method.

Add the final two methods as shown next:

void drawEnlargedBitmap(){

   bobBitmap = Bitmap

                .createScaledBitmap(bobBitmap,

                            300, 400, false);

   myCanvas.drawBitmap(bobBitmap, 25,25, myPaint);

}

void drawShrunkenBitmap(){

   bobBitmap = Bitmap

                .createScaledBitmap(bobBitmap,

                            50, 75, false);

   myCanvas.drawBitmap(bobBitmap, 250,25, myPaint);

}

The drawEnlargedBitmap method uses the createScaledBitmap method, which is 300 by 400 pixels. The drawBitmap method then draws it to the screen.

drawShrunkenBitmap uses the exact same technique except it scales then draws a 50 by 75-pixel image.

Run the app to see Bob grow, then shrink, then spin around through 360 degrees at 30-degree intervals, as shown in this next screenshot:

Figure 20.7 – How the app runs

Figure 20.7 – How the app runs

The only thing missing from our drawing repertoire is the ability to watch all this activity as it happens.

And that’s the end of learning Drawing Graphics in Android Canvas in Android Studio.

Learn more about Android Development

Written by

XR Developer responsible for end-to-end development of XR solutions spanning multiple domains, by using various XR and WebXR libraries.

Leave a Reply