Outline

In this week’s lab you will:

  1. create a new social-networking platform for sharing pictures of cereal

  2. ???

  3. profit!!!

But seriously, you’ll:

  • keep practising your “loop a function over some objects” skills

  • learn about image processing in p5

Pre-lab checklist

Before you attend your lab session, make sure:

  • you can fork, pull & push to GitLab

  • you understand the basics of objects: especially what properties and methods are (as covered in the week 5 lecture)

  • you’re aware that all the p5 functionality to do with images is bundled together inside the p5.Image object (see the reference for a refresher)

Introduction

Find a partner in your labs Teams channel! If someone has advertised themselves but not found a partner, reply to their comment and a tutor will set up a meeting for you to collaborate in. If no-one is currently advertising, make a message advertising yourself. There isn’t going to be much actual pair-work today, but it’ll still be nice to have someone to bounce ideas off of while you’re working!

We (humans) are visual creatures. We drew pictures of antelopes on cave walls for a long time, and then we invented the internet and now we have instagram1. And you know another thing that humans like doing? Eating breakfast cereal.

Send a message to your labs Teams channel—how could you exploit people’s love of pictures and eating cereal to make 1 billion dollars?

Since you’re in lab 8 now the lab content won’t hold your hand quite as much as in earlier labs. But if you get stuck, don’t feel like you have to just sit there and do nothing—ask your partner for some help, or message one of your tutors. Remember, we’re all on this learning journey together.

Fork and then clone the lab 8 template repo, open it in VSCode and start the live server as usual. You’ll notice there’s a number in the bottom-right corner of your sketch—this is part of the template. It’s showing the current frames per second reading (FPS) so it’s an indication of how smoothly your sketch is running. If everything’s going fine, it’ll hover around 60.

Part 1: setting the scene

Yep, that’s right, we’re going to create a new social network (or at least the interface for one). This social network is called Instagrains and the motto is:

Bringing people together. Through cereal.

Inspiring stuff. Because the motto is about bringing people together, you’re going to need a way to show where the people are—i.e. a map.

Using Google image search, find a map of Canberra/Australia/the world (your choice) to use as a “backdrop” for your Instagrains sketch. Make sure that the image is available under a suitable licence (e.g. creative commons). Once you’ve found one, save it into your assets/ folder (you’ll notice there are bunch of other image files in there as well—you’ll use them soon but just ignore them for the moment).

You know the background() function you’ve been using all along? Well, you can use an image as your background (instead of just a plain colour).

In your sketch, create a new p5.Image object using loadImage() and pass it as the argument to background(). Remember to declare a variable (call it whatever you like) to keep track of this image object.

Here’s a hot tip—try creating the image object inside the preload() function instead of the usual setup() one. They both happen just once at the start of the sketch, but the preload() function is a bit nicer for things which take a bit of time—they present the viewer with a “loading…” message, which is better than a blank screen.

One of the challenges with image loading (or other heavy processing in p5) is that from a responsiveness perspective you want to do all the time-consuming “loading” work at the start (so that once the sketch is running then it runs smoothly). However, one problem with the preload() and setup() functions is that they’re called before p5 knows the width and height of the canvas, so those variables are set to 0 at that time (this may have caused you problems in the past). One way around this is to use windowWidth and windowHeight, which are defined in preload() and setup(). Can you think of other solutions?

Once you’ve got your background image filling your whole canvas, remember that it’s a background image, so you don’t want it to stand out too much. One way to deal with this is to do a bit of image processing using one of p5’s built-in image filters. These are methods (functions which are properties of the object itself) so you’ll need to use the dot syntax to access them, e.g.

bgImage.filter(BLUR, 10);

There are a few different filters available (and the parameters mean different things for each one). Have a look at the reference for the full list, although remember that you want to call the filter method on a p5.Image object (e.g. bgImage.filter()), not the plain filter() function (which applies the filter to the whole canvas)

Once you’ve got a subtle, not-too-distracting background for the Instagrains interface it’s time to move on to the next part.

Part 2: share your cereal with the world

The basic component of Instagrains v1.0 is called a grain, which is just:

  • a photo of some cereal
  • the location of the person who’s eating it

That’s it—pretty simple, hey. It’s all about the MVP.

Send a message to your labs Teams chat—what can you tell about how the interface is going to work when you’re done? What parts do you think you’ll be implementing in today’s lab?

Someone else on the Instagrain team has already implemented the “upload the photo” functionality, so the image files are already in the assets/ folder (as .jpg files). Your job in this part is to write the code to draw these photos on the map background you made in part 1.

If you look at the top of sketch.js, you’ll notice an array of strings—each of these is the filename of a “cereal bowl” image in your assets/ folder.

createGrain()

You’ll notice that there’s a createGrain() function “skeleton” provided in the template—it doesn’t do anything at first, but your job in this part is to write the code so that it:

  1. takes a filename and x and y parameters as input (this is already there in the skeleton)

  2. loads that image from the assets/ folder

  3. returns an object which contains all the stuff essential to using the grain in the future

The template contains code to call createGrain() every second to create a new grain (as long as there are still new pictures of grain bowls).

Fill out the createGrain() function in the template so that it actually does something useful (although you won’t see it on the screen until you write the drawGrain() function—which you’ll do next).

drawGrain()

The createGrain() function doesn’t draw the grain on the map. That’s drawGrain()’s job. This time there’s no skeleton—you get to write the full function yourself.

What arguments should the drawGrain() function take?

Write the drawGrain() function. Once createGrain() and drawGrain() are working together, use a for loop over the grains array to draw them all on the map.

Once you’re drawing your grain bowl pictures on the map, then Instagrain v1.0 is done. Congratulations!

Part 3: make it interesting

You can probably think of lots of ways to make this better, though. Here are a few ideas, but don’t feel limited to this list. If you come up with some other cool idea then you should try to build it—ask your tutor for ideas on how to make it happen if you’re not sure how you’d do it.

  1. make each grain show up in a particular place that you choose

  2. make the interface change over time (so it’s not so static)

  3. add filters (i.e. can you do some image processing on the grains)

  4. make it so that when you click on a grain bowl, something happens?

  5. add captions (maybe even hashtags) for each grain bowl

  6. cycle through multiple images for each Instagrain user (i.e. make a gif)

  7. add sound to the sketch (if you do, remember to add the p5.Sound library to your sketch

  8. re-design the interface to make a statement about how ridiculous it is that we spend so much time and energy looking at pictures of food on our phones

As you try things, watch the “speedo” in the bottom left-hand corner—are there some things in particular which make the frame rate drop?

Break it down: scintillating pixels

An alternate way to do image processing is to get and set the colours of the individual pixels directly. p5.Image provides two methods for doing this:

  • .get(x, y) returns the colour of the pixel at position x, y

  • .set(x, y, color) allows you to set the colour of the pixel at position x, y

Scintillating Pixels is a famous2 sketch by Tim Brook which uses a couple of nested loops to create interesting pixel patterns:

Don’t be fooled by the simplicity of this code. I’ve seen people do amazing things with it. In fact it was run as a contest when Kieran took COMP1720.

What are the advantages/disadvantages of this “direct pixel manipulation” approach vs the built-in image filters you used earlier in the lab?

Summary

Congratulations! In this lab you:

  • practiced your “loop a function over some objects in an array” skills

  • learned about image processing in p5

  • created a new social-networking platform for sharing pictures of cereal and made the world a better place

Remember to commit your code and push it up to Gitlab, and log out of the lab computer. If you made a real difference in the world, you can share it with your friends using the test URL: https://comp1720.cecs.anu.edu.au/uXXXXXXX/lab-8/

  1. I think a few things happened in the middle as well, but hey—this isn’t a history course. You’ll have to go somewhere else to learn that stuff :) 

  2. famous by COMP1720 standards, anyway 

Updated:    11 Jan 2021 / Responsible Officer:    Head of School / Page Contact:    Charles Martin