2D Graphics: Part 1 Android Graphics Libraries • 2D Graphics – custom 2D graphics library in packages • android.graphics • android.graphics.drawable • android.graphics.drawable.shapes • android.view.animation • 3D Graphics – OpenGL ES (subset of OpenGL for embedded systems) in packages • android.opengl • javax.microedition.khronos.opengles The slides in this section will concentrate on the 2D graphics library. ©SoftMoore Consulting Slide 2 Hardware Acceleration • Android 3.0 (Honeycomb) included a new 2D rendering pipeline designed to support hardware acceleration. – primarily for tablets originally – all drawing operations carried out using the GPU • Android 4.0 (Ice Cream Sandwich) contained an improved version of the hardware-accelerated 2D rendering pipeline. – extended hardware acceleration to phones – on by default for all applications at API levels 4.0 and above – can be turned on for applications at lower API levels by adding android:hardwareAccelerated="true" to the <application> element in AndroidManifest.xml ©SoftMoore Consulting Slide 3 Drawing – Basic Concepts • An application that does not require a significant amount of processing or frame-rate speed will typically create a custom View component and draw onto a Canvas in the view’s onDraw() callback method. – A Canvas is passed as a parameter to this method. • The onDraw() method is called by the Android framework to request that a View draw itself. • An application can request that it’s View be redrawn by calling invalidate(), which causes Android to then call the onDraw() method. – Note that the callback to onDraw() is not guaranteed to be instantaneous. ©SoftMoore Consulting Slide 4 Main Classes Used in 2D Graphics • Color – alpha (opaqueness), red, green, blue • Paint – brush, style, fill, paint, font, font metrics…. • Bitmap – holds the actual pixels being drawn • Canvas – a way to draw to the screen or bitmap – supports 2D transforms (scale, translate, rotate) – drawing is actually performed on an underlying Bitmap – has primitives for drawing lines, circles, rectangles, text, etc. • Path – circles, rectangles, shape text, clipping shapes • Drawable – for things that know how to draw on a canvas ©SoftMoore Consulting Slide 5 Class Color • Colors are implemented as four bytes representing the alpha, red, green, and blue components – all four bytes are packed into a 32-bit integer (type int) – each component has a value between 0 and 255 (00 and FF hex) – alpha is a measure of transparency – 0 for fully transparent • Constants in class Color (type int) – – – – • BLACK DKGRAY LTGRAY TRANSPARENT – – – – BLUE GRAY MAGENTA WHITE – – – – CYAN GREEN RED YELLOW Static method to create a color object static int argb(int alpha, int red, int green, int blue) ©SoftMoore Consulting Slide 6 Obtaining a Color Object (All color values below are equal.) • Use one of the predefined constants in class Color int color1 = Color.MAGENTA; • Use the static method argb() int color2 = Color.argb(255, 255, 0, 255); int color3 = Color.argb(0xFF, 0xFF, 0x00, 0xFF); • Defined in a resource file (colors.xml) <?xml version="1.0" encoding="utf-8"?> <resources> <color name="magenta">#FFFF00FF</color> (* see note) </resources> ... int color4 = getResources().getColor(R.color.magenta); Note: If only three values are specified for a color, then the alpha component is assumed to be 255 (i.e., opaque). ©SoftMoore Consulting Slide 7 Class Paint • A Paint object holds the style and color information about how to draw geometries, text, and bitmaps. • Selected methods in class Paint – – – – – – – void setColor(int color) void setStrokeWidth(float width) void setStyle(Paint.Style style) void setTextAlign(Paint.Align align) void setTextSize(float textSize) Typeface setTypeface(Typeface typeface) void setUnderlineText(boolean underlineText) ©SoftMoore Consulting Slide 8 Example: Using Class Paint Paint paint = new Paint(); paint.setAntiAlias(true); paint.setColor(Color.MAGENTA); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(2); Notes: 1. Antialiasing reduces jagged edges for bitmap images to give a smoother appearance. 2. Calling setAnitAlias(true) is equivalent to calling setFlags(Paint.ANTI_ALIAS_FLAG); 3. Style STROKE is used to paint the perimeter of the circle. The default style is FILL. ©SoftMoore Consulting Slide 9 Class Canvas • Think of a Canvas as representing the surface on which you draw, but technically drawing is actually performed on an underlying Bitmap. • Features provided by class Canvas – contains primitives for drawing lines, circles, rectangles, text, etc. – provides support for clipping (restriction of an image to a specified subregion of the canvas in order to protect other portions of the canvas. Primitives lying outside the clip region are not drawn. – implements 2D transforms scale, translate, and rotate ©SoftMoore Consulting Slide 10 Selected Methods in Class Canvas • void drawCircle(float cx, float cy, float radius, Paint paint) – Draw the specified circle using the specified paint. • void drawColor(int color) – Fill the entire canvas bitmap with the specified color. • public void drawLine (float startX, float startY, float stopX, float stopY, Paint paint) – Draw a line segment with the specified coordinates and paint. • void drawLines(float[] pts, Paint paint) – Draw a series of lines. Each line is taken from 4 consecutive values in the pts array. ©SoftMoore Consulting Slide 11 Selected Methods in Class Canvas (continued) • void drawPath(Path path, Paint paint) – Draw the specified path using the specified paint. • void drawRect(float left, float top, float right, float bottom, Paint paint) – Draw the specified Rect using the specified paint. • void drawRoundRect(RectF rect, float rx, float ry, Paint paint) – Draw the specified rounded rectangle using the specified paint. • void drawText(String text, float x, float y, Paint paint) – Draw the text, with origin at (x,y), using the specified paint. ©SoftMoore Consulting Slide 12 Example: Drawing a Circle public class GraphicsView extends View { public GraphicsView(Context context) { super(context); } @Override protected void onDraw(Canvas canvas) { (implementation continued to next slide) ... } } Basic Idea: Extend the View class. Put drawing code in the onDraw() method. ©SoftMoore Consulting Slide 13 Example: Drawing a Circle (continued) protected void onDraw(Canvas canvas) { Paint paint = new Paint(); paint.setAntiAlias(true); paint.setColor(Color.MAGENTA); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(2); float centerX = getWidth()/2; float centerY = getHeight()/2; float radius = (centerX <= centerY ? centerX : centerY)/2; canvas.drawColor(Color.WHITE); canvas.drawCircle(centerX, centerY, radius, paint); } ©SoftMoore Consulting Slide 14 Example: Drawing a Circle (continued) public class MainActivity extends ActionBarActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new GraphicsView(this)); } } Note: This activity does not use a layout file. ©SoftMoore Consulting Slide 15 Example: Drawing a Circle (continued) ©SoftMoore Consulting Slide 16 Custom View Class in XML Resource File • Refer to the custom View class in an XML layout file using the “view” tag. • Example <LinearLayout ... <view class="edu.citadel.android.graphics2d.GraphicsView" android:id="@+id/graphics_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> If you use regular (non-inner) classes, you can replace <view class="edu.citadel.android.graphics2d.GraphicsView" …/> with <edu.citadel.android.graphics2d.GraphicsView …/> ©SoftMoore Consulting Slide 17 Class Path • Class Path encapsulates compound geometric paths consisting of straight line segments and curves. – can be drawn with canvas.drawPath(path, paint) • Enum Path.Direction – CCW (for counter-clockwise) – CW (for clockwise) • Enum Path.FillType – – – – EVEN_ODD INVERSE_EVEN_ODD INVERSE_WINDING WINDING ©SoftMoore Consulting Slide 18 Selected Methods in Class Path • void addCircle(float x, float y, float radius, Path.Direction dir) – Add a closed circle contour to the path. • void addOval(RectF oval, Path.Direction dir) – Add a closed oval contour to the path. • void addRect(float left, float top, float right, float bottom, Path.Direction dir) – Add a closed rectangle contour to the path. • void addRoundRect(RectF rect, float[] radii, Path.Direction dir) – Add a closed round-rectangle contour to the path. ©SoftMoore Consulting Slide 19 Selected Methods in Class Path (continued) • void close() – Close the current contour. • void lineTo(float x, float y) – Add a line from the last point to the specified point (x,y). • void moveTo(float x, float y) – Set the beginning of the next contour to the point (x,y). • void setFillType(Path.FillType ft) – Set the path's fill type. • void transform(Matrix matrix) – Transform the points in this path by matrix. ©SoftMoore Consulting Slide 20 Example: Using Class Path to Draw a Circle Same as the “Draw Circle” example except that the line canvas.drawCircle(centerX, centerY, radius, paint); is replaced by Path circle = new Path(); circle.addCircle(centerX, centerY, radius, Direction.CW); canvas.drawPath(circle, paint); ©SoftMoore Consulting Slide 21 Drawing Text • Among the most important Canvas draw methods are those used to draw text since, unlike some drawing commands, text rendering capabilities are not duplicated in other Android classes. • The basic draw methods simply draws the text starting at coordinates passed as parameters. void drawText(String text, float x, float y, Paint paint) • It is also possible to draw text along a Path. For a Path that defines a circle, the text is drawn in the same direction (clockwise/counterclockwise) as the circle. void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) ©SoftMoore Consulting Slide 22 Drawing Text (continued) • It is also possible to specify the exact position of each character in the text. void drawPosText(String text, float[] pos, Paint paint) ©SoftMoore Consulting Slide 23 Example: Drawing Text on a Path (continued) @Override protected void onDraw(Canvas canvas) { Paint paint = new Paint(); paint.setAntiAlias(true); paint.setColor(Color.BLUE); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(2); float centerX = getWidth()/2; float centerY = getHeight()/2; // set radius to 3/4 of the smaller dimension float radius = (3*(centerX <= centerY ? centerX : centerY))/4; (continued on next slide) ©SoftMoore Consulting Slide 24 Example: Drawing Text on a Path (continued) canvas.drawColor(Color.WHITE); Path circle = new Path(); circle.addCircle(centerX, centerY, radius, Direction.CW); canvas.drawPath(circle, paint); int textSize = 35; paint.setTextSize(textSize); paint.setStyle(Paint.Style.FILL); paint.setStrokeWidth(1); String quote = getContext().getString(R.string.quote); (continued on next slide) ©SoftMoore Consulting Slide 25 Example: Drawing Text on a Path (continued) // draw text three fourths the distance around the circle float threeFourths = (float)(3*Math.PI*radius)/2; // approx. path length of the quote float strPathLength = (float) quote.length()*textSize*0.205); float hOffset = threeFourths - strPathLength; canvas.drawTextOnPath(quote, circle, hOffset, textSize, paint); } ©SoftMoore Consulting Slide 26 Example: Drawing Text on a Path (continued) ©SoftMoore Consulting Slide 27 Relevant Links • Canvas and Drawables http://developer.android.com/guide/topics/graphics/2d-graphics.html • Android Programming: 2D Drawing Part 1: Using onDraw http://www.coreservlets.com/android-tutorial/ • API Demos (Graphics Demos) <ANDROID_SDK_HOME>\samples\<API_LEVEL>\ApiDemos (possibly also on your Android phone) • Android Development: 2D Grahpics http://www.linuxtopia.org/online_books/android/devguide/guide/topics/graphics/2d-graphics.html ©SoftMoore Consulting Slide 28