To draw something, you first need a canvas to draw on. We will use java.awt.image.BufferedImage, a bitmapped image that you create by providing the desired width and height in pixels.
When you are done drawing, you can save the image to a file using the javax.imageio.ImageIO.write function.
Here is a complete example that shows some drawing functions (drawing.kts):
import java.awt.image.BufferedImage import org.otfried.cs109ui.ImageCanvas import org.otfried.cs109.Color import org.otfried.cs109.DrawStyle // Size of image val w = 500 val h = 500 // create an image val image = BufferedImage(w, h, BufferedImage.TYPE_INT_RGB) // get ImageCanvas for the image val g = ImageCanvas(image) // clear background g.clear(Color.WHITE) // draw two filled circles g.setColor(Color.RED) g.drawCircle(50.0, 50.0, 20.0) // FILL is the default g.setColor(Color.ORANGE) g.drawCircle(250.0, 400.0, 20.0) // draw an unfilled circle with a pen of width 3 g.setColor(Color.MAGENTA) g.setLineWidth(3.0) g.drawCircle(415.0, 50.0, 15.0, DrawStyle.STROKE) // draw a filled and an unfilled Rectangle g.setColor(Color.CYAN) g.drawRectangle(20.0, 400.0, 50.0, 20.0, DrawStyle.FILL) g.drawRectangle(400.0, 400.0, 50.0, 20.0, DrawStyle.STROKE) // draw a line g.setLineWidth(1.0) // reset to default g.setColor(Color(0, 0, 255)) // same as Color.BLUE g.beginShape() g.moveTo(50.0, 50.0) g.lineTo(250.0, 400.0) g.drawShape(DrawStyle.STROKE) // draw a non-convex quadrilateral: g.save() // save current coordinate system g.translate(360.0, 260.0) // move origin to here g.rotate(-30.0) // rotate 30 degrees counter-clockwise g.beginShape() g.moveTo(0.0, 0.0) g.lineTo(30.0, -40.0) g.lineTo(60.0, 0.0) g.lineTo(30.0, -100.0) g.closePath() g.drawShape() g.restore() // restore current coordinate system // draw some text g.setColor(Color(0, 128, 0)) // a darker green g.setFont(20.0, "Batang") g.drawText("Hello World!", 155.0, 225.0) g.drawText("안녕 하세요", 175.0, 245.0) // done with drawing g.done() // write image to a file javax.imageio.ImageIO.write(image, "png", java.io.File("drawing.png"))
The generated drawing looks like this:
Colors are specified using an org.otfried.cs109.Color object. There are some predefined colors:
val color = Color(0, 200, 0) // slightly darker greenYou can also construct a color from a 24-bit integer:
val color = Color(0x00c800) // slightly darker green
Every shape can be drawn in two ways: either as a filled shape, or by drawing with a "pen" along the outline of the shape (or both).
You select the drawing style with one of the constants
To draw text, you need to set a font on the ImageCanvas using setFont. You can just provide a point size like this:
canvas.setFont(16.0)or set a different typeface by using one of the standard names "Monospaced", "Serif", or "SansSerif", or the name of a real font installed on your system:
When calling drawText, you have the choice to align the text at its left edge, the right edge, or its horizontal center. The alignment is selected with the constants
The org.otfried.cs109ui.ImageCanvas object does all the drawing. You can use its width and height properties to inquire the size of the canvas (but of course you can also check the original BufferedImage).
The basic methods of ImageCanvas are:
To draw shapes other than rectangles and circles, you need to use the shape methods of ImageCanvas:
You describe the shape by walking along the outline. First, call beginShape(), then moveTo(x, y) to go to the starting point of the outline. Now make a sequence of lineTo(x, y) calls to describe the boundary of the shape. You can complete the outline by calling closePath(), this returns to the starting point (which you set when you called moveTo(x, y)). For filled shapes you normally want to call closePath, for outlined (stroked) shapes it depends if you want the shape to be a closed curve or not.
Finally, call drawShape to draw the shape.
You can modify the coordinate system to make it easier to specify your objects:
Often you only want to modify the coordinate system temporarily, and return to the original coordinate system when you are done with some part of the drawing (see the quadrilateral in the code above). This is achieved by calling save() before changing the coordinate system, and restore() when you want to return to the previous settings.
Normally, shapes that are drawn later cover shapes that have been drawn before (the so-called "painter's model" of computer graphics).
However, you can call setAlpha(alpha) to set a transparency for future drawing operations. When alpha == 255, drawing is opaque and completely covers what was drawn before. When alpha == 128, you are drawing with 50% transparency: The result is a blend of half the original color and half the newly drawn color.
The method textWidth(text: String) returns the width of the text if you were to draw it now with the current transformation and font settings.