Start by reading about working with bitmaps in Scala.
Sepia is a color-toning technique that makes a photo look as if it was taken in the early twentieth century. Here is a comparison of black-and-white versus sepia versions of the same photo:
Write a function sepia that will convert a photo to sepia and returns a new image (the function does not modify the input image):
def sepia(img: BufferedImage): BufferedImage =For each pixel of the photo,
val v = (0.299 * red + 0.587 * green + 0.114 * blue).toInt
Posterizing means to replace the colors in a photo with a rather small set of colors (maybe ten). To posterize a photo, you first make a list of allowed colors. Then you look at every pixel of the photo, and replace it by the color from the list that is most similar. Write a function posterize that performs the second step:
def posterize(img: BufferedImage, colors: Array[Int]): BufferedImage =(Again, your function returns a new image and does not modify the input image.)
To do this, you will need to measure the distance between two colors \((r_1, g_1, b_1)\) and \((r_2, g_2, b_2)\). The natural way to do this is to measure the distance like the (squared) Euclidean distance of three-dimensional vectors:
Write a function to compute the distance between two colors!
To test your function, you'll need to create a list of colors. Test first with a fixed list of colors like this:
val colorList = Array(0xff0000, 0x00ff00, 0x0000ff, 0x000000, 0xffffff)
The result should like somewhat like this:
Then try other ways to select a color list. One possibility is to simple use a few random colors, for instance using this code:
def randomColor(): Int = (math.random * 0x1000000).toInt
Write a function that generates \(k\) random colors:
def randomColors(k: Int): Array[Int] =
Here is what I got using 10 random colors (of course it will look different every time you run it):
Let's now consider the problem of selecting colors that are adapted to the photo you want to posterize. Here is a method for doing this (\(k\) is the number of colors we want to choose):
You can now use \(c_1, c_2, \ldots, c_k\) to posterize the photo. Write a function
def selectColors(img: BufferedImage, k: Int): Array[Int] =
How do newspapers print photos? Ink is black, paper is white—there is no "gray ink". And still newspapers can print photos.
Can you create a version of a photo that only uses black and white pixels, and still creates the impression of gray levels?
One idea would be to represent each pixel of the photo using a small block of pixels. Depending on how many pixels in this block you turn black, you can achieve the impression of different gray levels.
Here is an example of how I implemented this.