Для чего нужен класс canvas java
Перейти к содержимому

Для чего нужен класс canvas java

  • автор:

Класс Canvas

Класс android.graphics.Canvas (Холст) предоставляет методы для рисования, которые отображают графические примитивы на исходном растровом изображении. При этом надо сначала подготовить кисть (класс Paint), который позволяет указывать, как именно графические примитивы должны отображаться на растровом изображении (цвет, обводка, стиль, сглаживание шрифта и т.д.).

Android поддерживает полупрозрачность, градиентные заливки, округлённые прямоугольники и сглаживание. Из-за ограниченных ресурсов векторная графика пока что не поддерживается, вместо этого используется традиционная растровая перерисовка.

Canvas работает с пикселями, поэтому следует заботиться о конвертации единиц dp в px и наоборот при необходимости. Начало координат находится в левом верхнем углу.

Получить доступ к холсту можно через объект Bitmap или компонент View. Очень часто разработчики создают свой собственный компонент, наследуясь от View, и рисуют на его холсте для реализации своих замыслов.

Методы

Ниже представлены некоторые методы класса Canvas, которые что-то рисуют.

  • drawARGB()/drawRGB()/drawColor(). Заполняет холст сплошным цветом. . Рисует дугу между двумя углами внутри заданной прямоугольной области. . Рисует растровое изображение на холсте. Вы можете изменять внешний вид целевой картинки, указывая итоговый размер или используя матрицу для преобразования.
  • drawBitmapMesh(). Рисует изображение с использованием сетки, с помощью которой можно управлять отображением итоговой картинки, перемещая точки внутри неё. . Рисует круг/окружность с определённым радиусом вокруг заданной точки. . Рисует линию (или последовательность линий) между двумя точками. . Рисует овал на основе прямоугольной области. . Закрашивает весь холст с помощью заданного объекта Paint. . Рисует указанный контур, используется для хранения набора графических примитивов в виде единого объекта.
  • drawPicture(). Рисует объект Picture внутри заданного прямоугольника. . Рисует точку в заданном месте.
  • drawPosText(). Рисует текстовую строку, учитывая смещение для каждого символа. . Рисует прямоугольник. . Рисует прямоугольник с закруглёнными углами. . Рисует текстовую строку на холсте. Шрифт, размер, цвет и свойства отображения текста задаются в соответствующем объекте Paint.
  • drawTextOnPath(). Рисует текст, который отображается вокруг определённого контура.
  • drawVertices(). Рисует набор треугольников в виде совокупности вершинных (вертексных) точек. . Вращение холста . Изменение и перемещение координатной системы

Мы уже изучали основы рисования в первом месяце обучения (Работаем с графикой. Основы). Можно вернуться к этому проекту, закомментировать код вывода графики и продолжить изучение рисования при помощи методов класса Canvas.

Метод drawArc()

В API 21 появилась перегруженная версия метода, в котором можно указать координаты двух точек вместо RectF.

Метод drawArc() позволяет рисовать дуги и сектора. Ниже приводится код для трёх вариантов: сектор с заливкой (похож на PacMan), сектор без заливки (контур) и часть дуги:

drawArc

Метод drawBitmap()

Вывести готовое изображение просто.

Метод drawCircle()

Первые два аргумента определяют координаты центра окружности/круга, следующий аргумент — её радиус в пикселах, последний — объект Paint. В зависимости от выбранного стиля кисти можно нарисовать закрашенный круг или только окружность.

Нарисуем зелёный круг.

No EmbossMaskFilter

drawLine(s)()

Простой метод — указываем начальные и конечные координаты отрезка.

drawLine

Метод drawOval()

Метод drawOval() рисует овалы. Естественно, если вы зададите одинаковые размеры ширины и высоты, то получите круг/окружность.

drawOval

Если вам нужно наклонить овал в ту или иную сторону, то поверните холст на требуемый угол с помощью метода rotate(). Не забудьте потом повернуть холст обратно, что следующие фигуры выводились нормально.

Повернём синий овал из предыдущего примера:

drawOval

В API 21 появилась перегруженная версия метода, в котором можно указать координаты двух точек вместо RectF:

Метод drawPaint()

Метод позволяет закрасить весь холст одним цветом.

Метод drawRect()

У метода существует три перегруженные версии для рисования прямоугольника. Рассмотрим один из них:

Метод drawRoundRect()

Для рисования прямоугольников с закруглёнными углами используется метод drawRoundRect (RectF rect, float rx, float ry, Paint paint).

В параметрах указываются ограничивающий прямоугольник, радиусы овалов для скругления углов и кисть.

Реализуем три разных способа:

drawRoundRect

В API 21 появилась перегруженная версия метода, в котором можно указать координаты двух точек вместо RectF.

Метод drawPath()

Для рисования соединённых отрезков можно использовать метод drawPath(), указав в параметрах настройки для рисования и массив координат точек. Для удобства добавим в класс Draw2D новый класс Pt, который позволит быстро создать массив точек с заданными координатами. Далее настраиваем объекты для рисования и формируем путь через созданный массив. В результате получим кошкин дом.

drawPath

Путь можно составлять не только из точек, но и из фигур, например, дуг. Сначала формируем дугу, добавляем её в путь при помощи метода Path.addArc(), повторяем операцию снова несколько раз, а в конце выводим окончательный вариант:

drawPath

Можно нарисовать символ парашюта:

addArc

Метод drawPoint()

Простой метод для рисования точки в нужно месте указанной кистью. Для координат используются значения типа float.

Метод drawText()

С помощью метода drawText() можно выводить текст в заданной позиции. Добавим сначала несколько эффектов, чтобы казалось, что текст парит над поверхностью:

drawText()

Центрируем текст

Есть небольшая тонкость, если вам захочется вывести текст в центре холста. Проблем с вычислением центра холста и размером текста нет. Центр можно найти, разделив пополам значения ширины и высоты холста. А ширину и высоту текста можно узнать через метод кисти getTextBounds(), который возвращает ограничивающий прямоугольник.

Но вычисление ширины текста через textBounds.width(); приводит к небольшому смещению. Лучше воспользоваться методом кисти measureText(). Тогда текст отцентрируется точнее.

drawText()

Пример на Kotlin с дополнительной информацией.

Методы rotate() и restore()

Холст во время рисования можно вращать. Во многих ситуациях такой приём менее затратный по ресурсам, чем рисование самого объекта под углом. Суть в следующем: вы поворачиваете холст на нужный градус, рисуете фигуру, а затем возвращаете холст на место при помощи метода restore(), чтобы следующие фигуры рисовались в ожидаемых местах. Иначе остальные фигуры будут рисоваться уже относительно поворота.

В примере с овалом уже использовался данный метод. В примере Работаем с графикой. Основы мы также поворачивали холст, чтобы вывести текст под углом.

Вращение происходит вокруг начальной точки холста (0, 0). Но можно также использовать перегруженную версию метода rotate(float degrees, float px, float py), в которой можно указать координаты точки поворота.

Методы scale() и translate()

Стандартная система координат начинает свой отсчёт с верхнего левого угла. Иногда, для рисования сложных фигур удобнее назначить свою систему координат. Например, для рисования циферблата часов удобнее рисовать относительно центра экрана в диапазоне от -1 до 1.

Чтобы установить свою систему координат, нужно произвести трансформацию. В следующем примере мы установим координаты в диапазоне от 0 до 10 и нарисуем график в стандартном виде из точки 0,0 в левом нижнем углу в точку 10,10 в верхнем правом углу.

Для наглядности я добавил на оси несколько точек. Следует обратить внимание, что мы задали диапазон от 0 до 10 и все размеры должны масштабироваться в новых величинах, в том числе и ширина обводки в методе setStrokeWidth(). Поэтому значения должны быть достаточно маленькими, иначе толщина обводки может просто оказаться больше самой фигуры. Кстати, в некоторых случаях с текстом и другими методами рисование масштабирование может сыграть злую шутку и дробные значения не позволят увидеть текст и некоторые линии. В этих случаях приходиться создавать цепочку преобразований, когда временно масштаб увеличивается до нормальных размеров, рисуется текст с подходящим размером шрифта, затем опять всё уменьшается и т.д. Это долгая история.

AWT Canvas Class

Canvas control represents a rectangular area where application can draw something or can receive inputs created by user.

Class declaration

Following is the declaration for java.awt.Canvas class:

Class constructors

Constructs a new Canvas.

Canvas(GraphicsConfiguration config)

Constructs a new Canvas given a GraphicsConfiguration object.

Class methods

void addNotify()

Creates the peer of the canvas.

void createBufferStrategy(int numBuffers)

Creates a new strategy for multi-buffering on this component.

void createBufferStrategy(int numBuffers, BufferCapabilities caps)

Creates a new strategy for multi-buffering on this component with the required buffer capabilities.

AccessibleContext getAccessibleContext()

Gets the AccessibleContext associated with this Canvas.

BufferStrategy getBufferStrategy()

Returns the BufferStrategy used by this component.

void paint(Graphics g)

Paints this canvas.

void pdate(Graphics g)

Updates this canvas.

Methods inherited

This class inherits methods from the following classes:

Canvas Example

Create the following java program using any editor of your choice in say D:/ > AWT > com > tutorialspoint > gui >

AwtControlDemo.java

Compile the program using command prompt. Go to D:/ > AWT and type the following command.

If no error comes that means compilation is successful. Run the program using following command.

11.1: The Canvas class

In Android, you have several techniques available for implementing custom 2D graphics and animations. Which techniques you choose depends on the type of graphics you want to display, as well as the needs of your app.

A Drawable is a graphic that can be drawn to the screen. You create Drawable objects for things such as textured buttons or frame-by-frame animations and display them into a standard or custom view. The drawing of your graphics is handled by the system's view hierarchy drawing process. Using a drawable is your best choice when you want to draw simple graphics that do not need to change dynamically and are not part of a performance-intensive game. For more informations, see Drawables and the chapter about drawables in Android Developer Fundamentals.

You can do your own custom 2D drawing using the drawing methods of the Canvas class. Draw to a Canvas when your app needs to regularly re-draw itself. In this chapter, you learn how to create and draw on a canvas.

  • SurfaceView

An instance of SurfaceView is a drawing surface that is part of your view hierarchy and managed and rendered by the system along with the view hierarchy. One of the purposes of this class is to provide a surface in which a secondary thread can render into the screen. The challenge is that you have to correctly manage your thread to only draw to the surface when it exists. The SurfaceView chapter includes an example of using a SurfaceView .

In addition, the following techniques are available but not covered in this course:

    . Beginning in Android 3.0, you can hardware-accelerate most of the drawing done by the Canvas APIs to further increase their performance. Android supports OpenGL ES 1.0 and 2.0 , with Android framework APIs as well as natively with the Native Development Kit (NDK). Using the framework APIs is desireable when you want to add a few graphical enhancements to your application that are not supported with the Canvas APIs, or if you desire platform independence and don't demand high performance.

What is a Canvas object?

When you want to draw shapes or text into a view on Android, you can do so via a Canvas object. Very simplified:

  • A Canvas is a 2D drawing surface that provides methods for drawing to a bitmap.
  • The bitmap, an instance of the Bitmap class is associated with a View instance that displays it.
  • A Paint object holds the style and color information about how to draw geometries (such as line, rectangle, oval, and paths), text, and bitmap.

Canvas defines shapes that you can draw on the screen, while Paint defines the color, style, font, and so forth, of each shape you draw.

The Canvas class also provides methods for clipping. Clipping is the action of defining geometrically what portion of the canvas is shown to the user in the view.

 In order to draw into a view, the view needs a bitmap, a canvas, and paint

The figure below shows all the pieces required to draw.

The types of operations you can perform on a canvas include:

  • Fill the whole canvas with color.
  • Draw shapes, such as rectangles, arcs, paths styled as defined in a Paint object.
  • Draw text styled by the properties in a Paint object.
  • Save the current Canvas state and restore a previous state.
  • Apply transformations, such as translation, scaling, or custom transformations.
  • Clip, that is, apply a shape or path to the Canvas that defines its visible portions.

Steps for creating and drawing on a Canvas object

After you have a project and activity, you need the following to work with a Canvas object.

Create a custom View class. You can extend any view that has the features you need. You do not need a custom View to draw, as discussed in the Simple Canvas practical. Typically you use a custom View so that you can draw by overriding the onDraw() method of the View .

public class MyCanvasView extends View

In onCreate() of the MainActivity , set the content View of the activity to be an instance of your custom View .

myCanvasView = new MyCanvasView(this); setContentView(myCanvasView);

In the constructor of the custom View , create a Paint object and set initial Paint properties. Initialize member variables and get a reference to the context. You cannot create your Canvas here because the View has not been inflated yet and thus has no size.

If any drawing is to happen in response to user motion, override onTouchEvent() . In this example, when the user drags their finger, and then lifts it off the screen, the x,y coordinates are handed off for some drawing action. You must call invalidate() every time the screen needs to be redrawn.

Drawing shapes and text

You can draw primitive shapes using predefined methods, and use a Path to create any shape you need.

  • Draw primitive shapes using drawRect() , drawOval() , and drawArc() . Change whether the shapes are filled, outlined, or both by calling setStyle() .
  • Draw more complex shapes using the Path class. Define a shape by adding lines and curves to a Path object, then draw the shape using drawPath() . As with primitive shapes, paths can be outlined, filled, or both, depending on the setStyle ().
  • Draw text using drawText() . Specify the typeface by calling setTypeface() , and the text color by calling setColor().
  • Define gradient fills by creating LinearGradient objects. Call setShader() to use your LinearGradient on filled shapes.
  • Draw bitmaps using drawBitmap() .

See the documentation for details of each method, and the practicals for examples on how these methods are used.

Transformations

Transformations are operations that change the canvas itself:

  • Use translate() to move the origin of the canvas. For example, when you are drawing the same shape in multiple places, instead of recalculating the shape, you can move the origin of the canvas and draw the same shape again. See the Applying clipping to a canvas practical for an example.
  • Use rotate to turn the Canvas by a number of degrees.
  • Skew the Canvas by calling the skew() method. You can achieve interesting effects with text using skewing.See the Canvas documentation for details on these and additional methods.

Clipping

Clipping is a method for defining regions of an image, canvas, or bitmap that are selectively drawn or not drawn onto the screen. One purpose of clipping is to reduce overdraw . When you reduce overdraw, you minimize the number of times a pixel or region of the display is drawn, in order to maximize drawing performance. You can also use clipping to create interesting effects in user interface design and animation.

The following screenshot from the Applying clipping to a canvas practical shows how you can clip and combine clipping regions.  Screenshot for the ClippingExample app.

Canvas provides methods for clipping, and you can also clip by defining a custom path.

    Use canvas.clipRect() to set a rectangular clipping region.

Define a Path and apply it with canvas.clipPath() for a custom clipping region. For example, to create a circular clipping region.

  • CCW stands for counterclockwise and indicates in which direction the circle should be drawn.
  • Region.Op.DIFFERENCE specifies how the clipping region should be applied to the canvas. See the Region.Op documentation for other operators.

Here is the code:

For a list of all clipping methods and supported operators for different versions of Android, see the Canvas documentation.

quickReject()

The quickReject() method allows you to check whether a specified rectangle or path would lie completely outside the currently visible regions, after all transformations have been applied.

The quickReject() method is incredibly useful when you are constructing more complex drawings and need to do so as fast as possible. With quickReject() , you can decide efficiently which objects you do not have to draw at all, and there is no need to write your own intersection logic.

  • The method returns true if the rectangle or path would not be visible at all. For partial overlaps, you still have to do your own checking.
  • The EdgeType is either AA (Antialiased: Treat edges by rounding-out, because they may be antialiased) or BW (Black-White: Treat edges by just rounding to nearest pixel boundary) for just rounding to the nearest pixel.
    boolean quickReject (float left, float top, float right, float bottom, Canvas.EdgeType type)
    boolean quickReject ( RectF rect, Canvas.EdgeType type)
    boolean quickReject ( Path path, Canvas.EdgeType type)

Saving and restoring a canvas

The activity context maintains a stack of drawing states. Each state includes the currently applied transformations and clipping regions. You can't remove clipping regions. Undoing a transformation by reversing it is error-prone, as well as chaining too many transformations relative to each other. Translation is straightforward to reverse, but if you also stretch, rotate, or custom deform, it gets complex quickly. Instead, save the state of the canvas, apply your transformations, draw, and then restore the previous state.

For a complete example, see the Clipping Canvas practical.

Related practicals

The related exercises and practical documentation is in Advanced Android: Practicals.

Learn more

Android developer docs:

    class class class class configurations operators class graphics tools Canvas configurations

Also see the Graphics Architecture series of articles for an in-depth explanation of how the Android framework draws to the screen.

Canvas

An essential part of programming in Java requires you to build exciting new user interfaces for yourselves. Components that come built into the Java framework are regular UI elements, however for a more rich experience, you need controls of your own. Take, for instance, a charting application. No charting tool comes built into a Java API. You need to manually draw the chart yourself.

Coding drawing, to begin with, is pretty daunting but once you know the basics of Graphics programming in Java, you can create elegant graphics and art in no time. But the question that arises in one’s mind is what to draw on. The answer to this question is simpler than it seems. You can start drawing on any component in the Java framework. Whether it be a panel, window or even a button.

Let me break it down for you. A component in the Java language is a class that has been derived from the Component class. Each component has a method with a signature paint(Graphics) which can be overridden to manually draw something atop it.

Overriding the paint(Graphics) method [ edit | edit source ]

Below is an example on how you need to override the above method. For this very example, the component class that we would be using would be the Canvas class. For more information about the Canvas class, see the section on Understanding the Canvas class

Understanding the Canvas class [ edit | edit source ]

Code listing 9.1 shows the simplicity and power of the syntax for enabling the graphics functions within Java. Lets begin by understanding what a Canvas class does. A Canvas class is a derivative or a sub-class of the Component class and when placed over a Frame , displays as a blank area.

For the purpose of drawing graphics, you may use any other class derived from the Component class, for instance, JPanel or even JTextField or JButton . Why we use the Canvas class is purely to grasp the idea of drawing in Java.

Note:
Notice the J before the names of each class. This suggests that the classes are part of the Java Swing library. Swing enables more freedom in drawing expressions in Java than AWT.

Let us refine the above code for the class to be executable and the Canvas to be displayed. For this we will add an entry-point method namely the main(String[]) method in its body and calling a JFrame class to load the canvas on.

The following code now helps our class to be executable and displays the canvas on top of the frame as it displays. Running this class would result in an empty frame, however it should be clear that the canvas is sitting atop it and is merely not displaying any drawings yet.

Figure 9.1: A blank canvas atop a JFrame

Get, set, draw! [ edit | edit source ]

Now that the basic structure of our program has been laid out, we need to explore how drawing is actually done by writing Java code. Move to the next section and try your hand at drawing basic shapes and lines. But whilst you are still fresh to the concept of a Canvas, why not test your knowledge. Try answering these questions below.

Question 9.1: What classes are used to draw in Java?

  1. Any class that is derived from the Object class.
  2. Any class that is derived from the Component class.
  3. None of the above.

2
A class derived from the Object class is not viable as a visible component, whereas a class derived from a Component class is a visible entity atop a Container hence a likely candidate for displaying drawings.

Question 9.2: What is the method that needs to be overridden in order to enable drawing?

  1. The main(String[]) method.
  2. The MyCanvas() method.
  3. The paint(Graphics) method.
  4. None of the above.

3
As discussed earlier the paint(Graphics) method is the correct option. The name says it all.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *