April 5, 2010

Graphics Basics

There are three main classes you will be working with when you do work with graphics and images in Android. These are:
Each of these three classes encompasses a great deal of functionality, which I explain in greater depth in later posts. For now, let's focus on what each of these classes are for, and how they work together.

Canvas
The canvas is exactly what its name implies. It represents a surface that can have things drawn to it. Imagine it as a piece of paper that you can draw shapes and images on. The Canvas class provides methods for you to:
  • Draw primitives such as simple shapes and paths
  • Draw bitmaps
  • Draw text
  • Clip drawing operations
  • Translate, scale, rotate, or otherwise transform the canvas's image
  • Save and restore drawing states
Paint
Think of the paint object as the physical brush you would hold in your hand when painting on a real canvas. You may have several different brushes that all have different properties, and you use each one for a different purpose. The Paint class in Android functions in a similar capacity. Whenever you want to draw to a Canvas object, you may also give a Paint object which contains the properties with which you want that drawing operation to use. You may have as many different paint objects as you like, and you can use any of them for each drawing operation performed on a canvas. The properties that a Paint object encapsulates are:
  • Drawing Color
  • Primitive drawing style (solid 'fill' or outline 'stroke')
  • Stroke style attributes
  • Fill shader
  • Text drawing font attributes
  • Color filter
  • Mask filter
  • Transfer mode
  • Shadow layer
Don't worry if the purpose of any of these is unclear, they will all be explained in detail in later posts.

Bitmap
Every canvas has exactly one underlying Bitmap object. The bitmap holds the actual pixel data of the image you are working with. Whereas the Canvas class provides a high level interface to draw shapes, paths, text, and so on, the Bitmap class provides a more low-level interface to the image, allowing you to manipulate the pixels directly.

Example
To demonstrate how these three classes work together, we'll create a simple Android app that draws a colored rectangle and displays it in an ImageView. Create a new Android activity in your editor of choice(are there any other choices besides Eclipse?), and add the following code as the activity's onCreate() method.
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // We'll be creating an image that is 100 pixels wide and 200 pixels tall.
    int width = 100;
    int height = 200;

    // Create a bitmap with the dimensions we defined above, and with a 16-bit pixel format. We'll
    // get a little more in depth with pixel formats in a later post.
    Bitmap bitmap = Bitmap.createBitmap(width, height, Config.RGB_565);

    // Create a paint object for us to draw with, and set our drawing color to blue.
    Paint paint = new Paint();
    paint.setColor(Color.BLUE);

    // Create a new canvas to draw on, and link it to the bitmap that we created above. Any drawing
    // operations performed on the canvas will have an immediate effect on the pixel data of the
    // bitmap.
    Canvas canvas = new Canvas(bitmap);

    // Fill the entire canvas with a red color.
    canvas.drawColor(Color.RED);

    // Draw a rectangle inside our image using the paint object we defined above. The rectangle's
    // upper left corner will be at (25,50), and the lower left corner will be at (75,150). Since we set
    // the paint object's color above, this rectangle will be blue.
    canvas.drawRect(25, 50, 75, 150, paint);

    // In order to display this image in our activity, we need to create a new ImageView that we
    // can display.
    ImageView imageView = new ImageView(this);

    // Set this ImageView's bitmap to the one we have drawn to.
    imageView.setImageBitmap(bitmap);

    // Create a simple layout and add our image view to it.
    RelativeLayout layout = new RelativeLayout(this);
    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
        LayoutParams.WRAP_CONTENT);
    params.addRule(RelativeLayout.CENTER_IN_PARENT);
    layout.addView(imageView, params);
    layout.setBackgroundColor(Color.BLACK);

    // Show this layout in our activity.
    setContentView(layout);
}

Push this to your device and you should have an activity that shows a blue rectangle within a red rectangle, centered over a black background.

13 comments:

  1. A slight error in the comments in the code:
    The blue rectangle has dimensions 50x75. Its upper left corner is indeed at (25,50) but the next two arguments specify the coordinates for the lower right corner, not the size.

    ReplyDelete
  2. Thanks for the correction. I've fixed the comment in the code.

    ReplyDelete
  3. Hey.. can I know how can I change the inner rectangle color (the red color) when I touch on it?

    ReplyDelete
  4. Thanks. I appreciate your time and effort in explaining about graphics.

    ReplyDelete
  5. wow. i've been searching for days for an easy enough explanation of android graphics classes and how they interact with each other.

    sometimes people just want simple answers to simple questions.


    i got your site bookmarked and i hope you write about animation and gestures soon too.

    great blog!

    ReplyDelete
  6. hello! you didnt mention you can set

    getWindow().setFormat(PixelFormat.RGBA_8888);

    before setting the contentView(R.layout.*)

    :)

    ReplyDelete
  7. Hey..Good example!!
    But Can you tell me how to draw rectangle on the image which is set to background with scroll bar,as the size of image is big..And i want the rectangle drawn on image should also move with image scrolled..in short the drawn rectangle should be stuck to particular position of the image

    ReplyDelete
  8. hey its very good example who started learning the graphics.
    But if i want to draw some thing on particular red color rectangle or blue color rectangle. how it is possible,can you provide code for it?

    ReplyDelete
  9. Thanks for the post. It covered all the basics of 2D graphics.

    ReplyDelete
  10. hello is there still somebody here??
    i've followed this tutorial great one by the way.. it helped me to understand what i'm doing till now.
    I'm wondering perhaps if you can help me with my project. My code always gets stuck at Canvas canvas = new Canvas(bitmap);

    ReplyDelete
  11. Thank you, thank you thank you!

    I have been fighting texture banding issues for several days and your article is the only one I have found that gave me any insight into the problem and it enabled me to fix it, and fix it by simply adding an alpha map to my png! You saved me a lot of work.

    ReplyDelete
  12. Thank you
    Good example, very easy to understand

    ReplyDelete
  13. Daredevil season 3 is going to be extremely absorbing as the show runners might bring back Elektra. Daredevil Season 3 Trailer

    ReplyDelete