Image

The Image DSL is the easiest way to create images using Doodle. The tradeoff the Image library makes is that it only support a (large but limited) subset of operations that are supported across all the backends.

Imports

To use Image you’ll need the following imports:

import doodle.image._
import doodle.image.syntax._
import doodle.core._

Basic Concepts

Image is based on composition and the interpreter pattern.

Composition basically means that we build big Images out of small Images. For example, if we have an Image describing a red square and an Image describing a blue square

val redSquare = Image.square(100).fillColor(Color.red)
// redSquare: Image = FillColor(
//   Rectangle(100.0, 100.0),
//   RGBA(
//     UnsignedByte(127),
//     UnsignedByte(-128),
//     UnsignedByte(-128),
//     Normalized(1.0)
//   )
// )
val blueSquare = Image.square(100).fillColor(Color.blue)
// blueSquare: Image = FillColor(
//   Rectangle(100.0, 100.0),
//   RGBA(
//     UnsignedByte(-128),
//     UnsignedByte(-128),
//     UnsignedByte(127),
//     Normalized(1.0)
//   )
// )

we can create an Image describing a red square next to a blue square by combining them together.

val combination = redSquare.beside(blueSquare)
// combination: Image = Beside(
//   FillColor(
//     Rectangle(100.0, 100.0),
//     RGBA(
//       UnsignedByte(127),
//       UnsignedByte(-128),
//       UnsignedByte(-128),
//       Normalized(1.0)
//     )
//   ),
//   FillColor(
//     Rectangle(100.0, 100.0),
//     RGBA(
//       UnsignedByte(-128),
//       UnsignedByte(-128),
//       UnsignedByte(127),
//       Normalized(1.0)
//     )
//   )
// )

The interpreter pattern means that we separate describing the Image from rendering it. Writing Image.square(100) doesn’t draw anything. To draw an image we need to call the draw() method. This separation is important for composition; if we were to immediately draw we would lose composition.

The source code for this page can be found here.