Images


Images


November 16, 2020

tutorial p5.js javascript image

Now you know how to use objects and create your own classes. You know how to create an instance of a class, store it in a variable, and then call functions belonging to that instance.

For example, you’ve seen the predefined p5.Vector class:

p5.js offers several other predefined classes. One of them is the p5.Image class, which lets you load, display, and manipulate image files.

Adding Files to Your Sketch

Before you can use an image file in your code, you have to add it to your sketch.

If you’re using the p5.js web editor:

  1. Click the > button just under the play button to expand the list of files in your sketch. You should see index.html, sketch.js, and style.css.
  2. Click the dropdown menu next to Sketch Files and then click Upload file.
  3. In the window that pops up, drag a file or click to select a file.
  4. When your file is done uploading, close the file selector window.

You should now see your image file in the list of Sketch Files. You can collapse the list of sketch files by clicking the < button.

Loading Images

After you’ve added an image file to your sketch, you can call the loadImage() function to create an instance of the p5.Image class.

For example, if you have an image file named stanley.jpg, you can create an instance of p5.Image like this:

let stanleyImage = loadImage("stanley.jpg");

You can also reference an image on the internet using its URL:

let stanleyImage = loadImage("https://happycoding.io/images/stanley-1.jpg");

Drawing Images

Now that you have an instance of PImage stored in a variable, you can display it by calling the image() function.

The image() function takes three parameters: an instance of PImage and x and y coordinates that tell Processing where to draw the image.

picture of Stanley

The image() function is just like the other drawing functions you’ve already seen, like the rect() and circle() functions. Try experimenting with different x and y parameters!

image following mouse

Note that these sketches declare the img variable at the top of the sketch, then initialize it inside the setup() function, and then display it in the draw() function. You should follow this pattern with your images as well. If you load your image in the draw() function, you’d be reading the same file 60 times every second, which could slow your program down or even cause it to crash.

Remember: declare your images at the top of the sketch, load them in setup(), and display them in draw().

Resizing Images

The p5.Image class contains several useful functions that let you manipulate images. For example, the resize() function resizes an image. Here’s an example that resizes the image whenever the user clicks the mouse:

resizing image

This is useful if you’re loading a large image and want to display it smaller.

Note that this only changes the size of the instance, not the file itself.

The p5.Color Class

The next few sections use a class you might not have seen before: the p5.Color class!

The p5.Color class represents an R, G, B color. You can create a color using the color() function. Then when you have a color value, you can pass it into any function that also takes R, G, B arguments.

colored squares

To convert from a p5.Color to individual R, G, and B, values, you can use the red(), green(), and blue() functions which take a p5.Color argument and return the corresponding R, G, or B value.

I personally avoid the p5.Color class because I prefer working with separate R, G, and B values. But the next few functions only work with the p5.Color type!

Getting Pixels

After you load an image, you can get the color of an individual pixel by calling the get() function.

Here’s an example:

sketch showing pixel color

This program uses the get() function to get the color of the pixel that’s under the cursor’s position, then displays a box showing that color. Think of it like a magnifying glass that shows you the pixel under the mouse.

Setting Pixels

Just like you can get the color of a specific pixel using the get() function, you can also set the color of a specific pixel using the loadPixels(), set(), and updatePixels() functions. Here’s an example that turns a random pixel black every frame:

image getting darker

The loadPixels() function tells p5.js to prepare the image’s pixels for changing, the set() function changes the color of a specific pixel, and the updatePixels() function tells p5.js to update the image with its new pixels.

Preloading Images

So far, the examples have loaded the images from the setup() function. That will work as long as you don’t need to use the image right away. But you’re going to have a problem if you do need to use the image right away, like if you need to get its width and height, or if you need to modify the pixels in the setup() function.

The loadImage() function is asynchronous, which means that the rest of the code keeps running while the image loads behind the scenes. This helps your sketch load faster, because it doesn’t have to wait until all of the images are loaded to start running.

But if you try to use the image right after you call loadImage(), but before the image is actually loaded, then it won’t work.

Here’s an example:

You might expect this code to show an image and then draw circles on top of that image. But if you run it, you’ll see that the image is not drawn! That’s because the image is not done loading when the code tries to draw it.

You can use the preload() function to fix this problem. The preload() function is called automatically, just before the setup() function. Any images loaded from inside the preload() function will be loaded before the sketch starts running. This means you might see a "Loading..." message when your sketch first starts, but it also means you can use your images right away.

inversed image

This code might seem complicated, but try to read through it one line at a time.

This line loops over every row in the image:

for(let y = 0; y < img.height; y++) {

For each row, this line loops over each column in that row:

for(let x = 0; x < img.width; x++) {

Given a row and a column (in other words, a y and an x), this line gets the color of that pixel:

color originalColor = img.get(x, y);

Now that you have the pixel’s color, you can inverse that color by subtracting the R, G, and B components from 255:

const r = 255 - red(originalColor);
const g = 255 - green(originalColor);
const b = 255 - blue(originalColor);
let outputColor = color(r, g, b);

If this part is confusing, try writing down some example colors and doing this math to see how it creates the inverse!

Finally, this line sets the color of the pixel to the newly calculated color:

img.set(x, y, outputColor);

Try modifying the logic to swap the blue and green of each pixel, or to divide the red by two, or to rearrange the pixels.

tinted image rearranged image

Other Image Functions

The p5.Image class contains several other useful functions. Check out the reference for more info about them. Don’t be afraid to experiment!

Homework

  • Take a colored image and display it as black and white.
  • Take a black and white image and display it in color. Don’t worry too much about getting the colors correct!
  • Show a character that walks around when you press the arrow keys. Use different images for the different poses.
  • Take an image and apply a custom filter to it.
  • Resize an image to display in the width and height of the window while maintaining its aspect ratio. Tall image should show a border on the left and right. Wide images should show a border on the top and bottom.

Images Examples

Comments

Happy Coding is a community of folks just like you learning about coding.
Do you have a comment or question? Post it here!

Comments are powered by the Happy Coding forum. This page has a corresponding forum post, and replies to that post show up as comments here. Click the button above to go to the forum to post a comment!