Areas, Text and Colours (Introduction to Computer Graphics Using Java 2D and 3D) Part 4

Colours in Java 2D

With the exception of the CNS model, Java 2D supports all colour models mentioned in the previous section. Because most applications are based on the RGB model, within this topic only this model will be used. The class Color allows to define colours based on RGB values using the constructor

tmpc009-197_thumb[2][2]_thumb

The values r, g, b are either float-values between zero and one, specifying the red, green and blue intensity, respectively, or they can be integer values between 0 and 255, defining the corresponding intensity levels for the colours. The class Color also provides some constants for standard colours, for instance Color.red or Color.yellow. Another constructor needs only a single integer parameter. From the byte coding of these integer values the corresponding byte values, yielding numbers between 0 and 255, for the three colours red, green and blue are derived. Integers are coded by four bytes. Colours can also use the fourth byte as the so-called alpha-value, which defines how transparent the colour is.


When the method

tmpc009-198_thumb[2][2][2]

is called, everything drawn with methods of the Graphics2D object g2d will be drawn in the colour col until setPaint is called again with another colour.

Colour Interpolation

Most of the colour models are based on a three-dimensional colour space in which colours are defined by three components. Within the RGB model a colour can be associated with a vector (r, g,b) e [0,1]3. This interpretation of colours also allows the definition of convex combinations of colours. One application of such convex combinations are colour gradients. If an area should not be filled with a homogeneous colour but with changing colour, this can be achieved by a colour gradient. Two colours (r0,g0,b0) and (r1,g1,b1) must be defined for two points p0 and P1. The colour (r0,g0,b0) is used in the point p0, the colour (r1,g1,b1) in the point p1 . For points on the connecting line between p0 and p1, the corresponding convex combination of the colours is used. For the point p = (1 – a)p1 + ap0 (where α e [0,1]) the colour (1 – α) · (r0,g0,b0) + α · (r1 ,g1,b1 ) is used.

Colour interpolation can also help to amend textures that are used repeatedly to fill an area. As mentioned in Sect. 4.1, fissures as in a tile pattern might occur at the boundaries of the texture. Image processing techniques include smoothing operators [5] to let edges appear less sharp. Simple smoothing operators are characterised by a weight matrix that defines how the colour values of pixels should be modified. For instance, the weight matrix means that the smoothing operator assigns a new colour to a pixel in the following way.

tmpc009-199_thumb[2][2][2]

The new colour is the weighted sum of the pixel’s colour with weight 0.2 and the colours of its eight neighbour pixels, each one with a weight of 0.1. The smoothing operator is applied to each pixel. Depending on how strong the smoothing effect should be, the weights can be changed, for instance all weights could have the same value 1/9 to achieve a stronger smoothing effect. The weight matrix can also be enlarged to take not only the colours of the direct neighbours of a pixel into account. For smooth transitions at the boundaries of a texture, the smoothing operator must be applied to pixels at the edges of the texture. For this purpose, the pixels on the right edge should be considered as left neighbours of the pixels at the left edge and vice versa. The same applies to the pixels at the lower and upper edge.

Interpolators were already discussed in Sect. 2.11 in the context of continuous movements of objects. These interpolators were based on geometric transformations. One application for such animated graphics was the transformation of one geometric object into another one by convex combinations of transformations. Another interesting example is the transformation of one image to another, which will be discussed here in more detail. The simplest way to transform two images of the same size into each other is to apply convex combinations of the intensity values of the corresponding intensities for red, green and blue at every pixel. This will lead to a continuous blending of the two images. Whilst one image fades away, the other one appears. More realistic effects can be achieved, when also the geometric shapes in the two images are transformed properly into each other. In this case, geometric transformations are also needed in addition to colour interpolation. A common technique that does more than just blending the two images is based on a triangulation of the two images. A triangulation is a partition using triangles. The two triangulations must use the same number of vertices and the triangles in the triangulations must be chosen accordingly. This means that if the points pi , pj and pk form a triangle of the triangulation in the first image, then the corresponding points in the second image must also form a triangle of the triangulation of the second image. It is not necessary that points which correspond to each other in the two images have the same coordinates.

Compatible triangulations of two images

Fig. 4.12 Compatible triangulations of two images

Each triangle of a triangulation determines a section of the corresponding image. Such a section has a corresponding section in the other image although the two triangles might be different in size and shape. Figure 4.12 illustrates this situation. On the left-hand side, two faces are shown that should be transformed into each other. The right part of the figure shows compatible triangulations of the two images. Each triangle is responsible for a certain section in the images. For instance, the upper triangle includes the forehead of the corresponding face, the lower triangle the chin. It should be noted that the number of points for the triangulation is identical for both images, but the points do not have the same positions.

In order to transform one image into the other step by step with intermediate images, first the triangulation of the corresponding intermediate image must be determined. The points for the triangulation result from convex combinations of the associated points in the two images. The triangles for the intermediate image are defined in the same way as for the other two images. If the points Pi, p;- and pk form a triangle in the first image and the associated points pi, p’;- and p’k form a triangle in the second image, then the points

tmpc009-201_thumb[2][2][2]

form a triangle in the intermediate image.

Within one triangle, the colour for the pixels is determined by colour interpolation. Before the colour of a pixel in the intermediate image can be computed, the triangle in which the pixel lies must be determined. If the pixel belongs to more than one triangle, in case it lies on an edge or a vertex of a triangle, then any of these triangles can be chosen. The task is to find out whether a pixel q lies within a triangle defined by the points pi, p2, p3. As long as the triangle is not degenerated to a line or a point, there is exactly one representation of q in the form

tmpc009-202_thumb[2][2][2]

Fig. 4.13 Computation of the interpolated colour of a pixel

Computation of the interpolated colour of a pixel

where

tmpc009-204_thumb[2][2][2]

This is a system of linear equations with three variables α1 , α2, α3 and three equations. The vector equation (4.1) contributes two equations, one for the x- and one for the y-coordinate. The third equation is the constraint (4.2). The point q lies within the triangle defined by the points p1, p2, p3 if and only if 0 < α1,α2,α3 < 1 holds, i.e., if q can be written as a convex combination of p1, p2, p3.

After the triangle in which the considered pixel lies and the corresponding values α1, α2, α3 have been determined, the colour of the pixel is calculated as a convex combination of the colours of the corresponding pixels in the first and the second image. The triangle in the intermediate image is associated to one triangle in the first and the second image. For each of these two triangles the convex combination of its vertices with weights α1, α2, α3 specifies the point corresponding to the considered pixel in the intermediate image. Rounding might be required to obtain a pixel from the point coordinates. The colour of the pixel in the intermediate image is a convex combination of the colours of these two pixels in the first and the second image.

Figure 4.13 illustrates this principle. The triangle in the middle belongs to the intermediate image in which the pixel lies for which the colour should be determined. The left and right triangle are the corresponding triangles in the first and the second image. The pixels in the three triangles originate from the same convex combination of the vertices in the corresponding triangle.

Colour Interpolation with Java 2D

The Java 2D class GradientPaint provides a simple way for colour interpolation or colour gradients. A colour gradient between the two points (x0,y0) and (x1,y1) can be defined by

tmpc009-205_thumb[2][2][2]

which is activated by g2d.setPaint(gradPaint);

The coordinates of the points should be float values. The colour0 is used in the point (x0,y0), the colour colour1 in point (x1,y1). Points on the line connecting these two points obtain their colour from the corresponding convex combi- nation of colour0 and colour1. The same colour gradient is applied to lines parallel to the connecting line between (x0,y0) and (x1,y1). The Boolean value repeat specifies whether the colour gradient should be repeated before (x0,y0) and after (x1,y1) .If false is chosen for repeat, then pixels before (x0,y0) are drawn with the colour colour0 and pixels behind (x1,y1) are drawn with the colour colouri. In case of true, the colour gradient is repeated again and again. Behind the point (x1,y1) the interpolation is continued from colour colour1 back to colour colour0, then again to colour1 etc. Thepoint (x0,y0) is treated analogously. The file GradientPaintExample.java demonstrates the use of GradientPaint.

Methods for colour gradients are provided in the class GradientPaint, but more general colour interpolation techniques as described at the end of Sect. 4.7 cannot be implemented by a simple GradientPaint. For these colour interpolation techniques, it is necessary to read and set the colour of pixels in an image. For this purpose, the following methods are available in Java 2D. The colour of the pixel with coordinates (x, y) in the BufferedImage bi can be obtained by

tmpc009-206_thumb[2][2][2]

The method getRGB(x,y) returns the colour as a single integer value in which each colour of the primary colours red, green and blue is encoded by one byte. In order to access the corresponding values red, green and blue directly, a new colour instance of the Color is generated from which the RGB values can be obtained by

tmpc009-207_thumb[2][2][2]

as integer values in the range from 0 to 255.

For interpolating or mixing the colours of a set of pixels, the colour of each pixel must be determined as described above. Then the corresponding values for red, green and blue can be combined as a suitable convex combination, depending on how the pixel colours should be interpolated or mixed. If rMix, gMix and bMix denote the interpolated values for the three colours, then the pixel with coordinates (x,y) in the BufferedImage mixedBi obtains this colour by

tmpc009-208_thumb[2][2][2]

The method setRGB requires the colour encoded in the form of an integer value, not as an instance of the class Color.

The class MorphingCandS.java uses this technique for colour interpolation in order to transform one image into another one step by step. For both images suitable compatible triangulations must be defined in advance. The interpolation between the two images, as described at the end of Sect. 4.7 and as illustrated in Fig. 4.13 on page 96, is carried out in the class TriangulatedImage.java.

Next post:

Previous post: