Introduction to the

After getting in touch with custom View, I often encounter Canvas and Paint. It is easy to understand Paint in terms of usage, but I am not clear about the relationship between Canvas, Bitmap and Drawable. I looked at the code today and tried to differentiate.

Canvas

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).
Copy the code

This is written in the Canvas class. If we want to draw something, we need:

  1. A Bitmap to hold pixels
  2. A Canvas hosts the draw call and draws it on a Bitmap
  3. A drawing prototype, such as rectangle, path, text, Bitmap
  4. A brush that describes the color and style of the drawing

From this we can know that the drawing call is passed to the Canvas, but the location of the drawing is drawn on a Bitmap.

So what is a Bitmap?

Bitmap

The bitmap is essentially an int[] buffer, which means there is a buffer that holds information for each pixel

The Canvas class has a Bitmap object:

public class Canvas extends BaseCanvas {...// may be null
  private Bitmap mBitmap;
  
  public Canvas(@NonNull Bitmap bitmap) {... mBitmap = bitmap; . }public void setBitmap(@Nullable Bitmap bitmap) {... mBitmap = bitmap; }}Copy the code

So the actual drawing is done on the Bitmap held by the Canvas

Drawable

Drawable is an abstraction that describes all Drawable objects. A Drawable is rarely used directly. A Drawable object is usually obtained using a Drawable resource.

The resource type The file suffix Drawable type
Bitmap File .png .jpg .gif BitmapDrawable
Nine-Patch File .9.png NinePatchDrawable
Shape Drawable .xml ShapeDrawable
State List .xml StateListDrawable

Relationship with View

public class View implements Drawable.Callback.KeyEvent.Callback.AccessibilityEventSource {...private Drawable mBackground; / / the background.public void setBackground(Drawable background) {
    setBackgroundDrawable(background);
  }

  @Deprecated
  public void setBackgroundDrawable(Drawable background) {... mBackground = background; . }public void draw(Canvas canvas) {...// Step 1, draw the background, if needed
    if (!dirtyOpaque) {
      drawBackground(canvas);
    }
    ...
  }

  private void drawBackground(Canvas canvas) {
    finalDrawable background = mBackground; . background.draw(canvas); . }@Override
  protected void onDraw(Canvas canvas) {}}Copy the code

conclusion

  • A Bitmap is simply a storage format that stores information about each pixel in a rectangular area. This format is good for display, but inefficient for storage.
  • Canvas is also a rectangular area, but it has no boundary. We can call any method starting with drawXXX on it to draw onto the referenced Bitmap. At the same time to provide graphics processing, such as cropping, scaling, rotation (need Matrix object with use). So Canvas is not so much a Canvas as a drawing tool
  • Drawable represents a graphic object that can be drawn, as well as visual objects such as gradients. Different Drawable subclasses can define different drawing methods, essentially drawing to a Bitmap using a Canvas.

If you have any questions, please point them out. Thank you W