L07. For expressions

In this lab, we will use matrices to encode Bitmap images. The format is called BPM, and more details are available here. Our format will be grayscale only. Each pixel of the matrix is encoded as an integer, with values from 0 to 255. Some examples are shown below:

    0 0 1 0 0
    0 1 0 1 0
    0 1 1 1 0    letter A
    1 0 0 0 1
    1 0 0 0 1
    
    5 4 3 2 1
    5 4 3 2 1
    5 4 3 2 1    shader
    5 4 3 2 1
    5 4 3 2 1

Add the following type definition for the rest of your lab:

type Img = List[List[Int]]

Also, in order to benefit from visualisation, instead of using a worksheet, you can create a new Scala project, containing an object with a main method:

object Matrix {
// define your functions here
 
  def main(args: Array[String]) = {
  // write your tests here
  }
}

7.1. Write a function which converts an image to a string (Hint: you can draw inspiration from a similar one from the lecture):

def show(m: Img): String = ???

7.2. Write a function which performs a horizontal flip on an image. Try to first visualise (you may use pen and paper) how the transformation would look like.

def hFlip(img: Img): Img = ???

7.3. Write a function which performs vertical flip.

def vFlip(img: Img): Img = ???

7.4. Write a function which performs a 90 degrees rotation to the right. (Hint: you need an ingredient from the lecture. Also, note that there are multiple possible implementations.)

def rot90Right(img: Img): Img = ???

7.5. Write a function which performs a 90 degrees rotation to the left.

def rot90Left(img: Img): Img = ???

7.6. Write a function which inverts an image (values 0 become 255, 1 - 254, and so forth).

7.7. Write a function which crops a given image, using two, two-dimensional coordinates: the higher-left point x and y, and the lower-right point x and y. An example is shown below:

val img = List(List(0,0,1,0,0), List(0,1,0,1,0), List(0,1,1,1,0), List(1,0,0,0,1), List(1,0,0,0,1))
/*
      0 0 1 0 0
*     0 1 0 1 0                                           1 0 1
*     0 1 1 1 0     cropping from 1,1  to  2,3  yields:   1 1 1
*     1 0 0 0 1
*     1 0 0 0 1
 
 */
 
def cropAt(img: Img, xSt:Int, ySt:Int, xEnd: Int, yEnd: Int): Img = ??

7.8. Write a function which returns a list of all positions which have pixels of larger intensity than x

def largerPos(img: Img, int: Int): List[(Int,Int)] = ???

7.9. Write a function which adds x to the intensity of each pixel.

def contrast(x: Int)(img: Img): Img = ???

7.10. Write a function which takes two images X and Y and glues them on the horizontal axis (the resulting image will be XY)

def hglue(img1: Img, img2: Img): Img = ???

7.11. Write a function which takes two images X and Y and glues them on the vertical axis:

def vglue(img1: Img, img2: Img): Img = ???

7.12. Define a function that takes a square image, and draws two diagonal lines of intensity 1 across it. Use _.until(_) and _.toList.

def diag(img: Img): Img = ???

7.13. Define a function which blurs an image as follows:

def blur(img: Img): Img = ???

7.14. (!) Define a function which builds an effect of intensity x as shown below:

val img2 = List(
  List(0,0,0,0,0,0,0,0,0),
  List(0,0,0,0,0,0,0,0,0),
  List(0,0,0,0,0,0,0,0,0),
  List(0,0,0,0,1,0,0,0,0),
  List(0,0,0,1,2,1,0,0,0),
  List(0,0,0,0,1,0,0,0,0),
  List(0,0,0,0,0,0,0,0,0),
  List(0,0,0,0,0,0,0,0,0),
  List(0,0,0,0,0,0,0,0,0)
)
 
/*
Before:                   After (for x = 2)
 
    0 0 0 0 0 0 0 0 0      0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0      0 0 1 1 1 1 1 0 0
    0 0 0 0 0 0 0 0 0      0 1 1 2 2 2 1 1 0
    0 0 0 0 1 0 0 0 0      0 1 2 2 3 2 2 1 0
    0 0 0 1 2 1 0 0 0      0 1 2 3 4 3 2 1 0
    0 0 0 0 1 0 0 0 0      0 1 2 2 3 2 2 1 0
    0 0 0 0 0 0 0 0 0      0 1 1 2 2 2 1 0 0
    0 0 0 0 0 0 0 0 0      0 0 1 1 1 1 1 0 0
    0 0 0 0 0 0 0 0 0      0 0 0 0 0 0 0 0 0
 
 
Hint: a single foldRight is sufficient. Which is the list you should apply it on?
 */
def effect(intensity: Int, img: Img): Img = ???