Group | Members |
---|---|
A | Talia, Jane |
B | Dorothy, Sachi |
C | Jonathan, Bateel |
D | Amber, Sanie |
E | Jennifer, Danielle |
F | Kim, Gabriel |
Be prepared to present your assessment and suggestions to the class. You will have 30 seconds.
pixel[]
data directly.Sketch! Explore working with images pixels.
Post at least one sketch for each of the following:
ellipse()
or rect()
.This week, most of your posts should be still images. You might also consider creating animations. Since p5 pixel access is slow, this technique will pair well with pre-rendering.
Create code that processes an image. Feed the result back into your code. Repeat. What happens after several generations? Post your source image, the result after one generation, and the result after several generations. Alternately, capture 90 generations as frames and post as a video.
Let’s look at the example above in depth:
Line 8 uses createImage()
to create a new, empty image in memory. We can draw this image just like an image lowed from a .jpg
or .gif
.
Line 9 uses loadPixels()
to tell p5 that we want to access the pixels of the image for reading or writing. You must call loadPixels()
before using set()
, get()
, or the pixels[]
array.
Lines 11 + 12 sets up a nested loop. The inner content of the loop will be run once for every pixel.
Line 13 uses the color()
function to create a color value, which is assigned to c
. Color values hold the R, G, B, and A values of a color. The color function takes into account the current colorMode()
.
Line 14 uses set()
to set the color of the pixel at x, y
.
Line 18 uses updatePixels()
to tell p5 we are done accessing the pixels of the image.
Line 20 uses noSmooth()
to tells p5 not to try to smooth the image when we scale it. This is like telling photoshop to use ‘nearest neighbor’ when scaling an image.
Line 21 draws the image, filling the canvas so we can clearly see each pixel.
This example has the same structure as the first one, but draws a gradient pixel-by-pixel.
The first two examples use a nested loop to set a value for every pixel in the image. This pattern often used in pixel generating and processing scripts, but not always. This example places red pixels at random places on the image.
Explore using p5’s pixel manipulation functions by modifying the scripts above. Work through the following challenges in order. Don’t skip any.
Time | Comment |
---|---|
< 13 in 20 Minutes | You need to put in some extra work to strengthen your programming understanding. |
13 in 20 Minutes | Good. |
All in 20 Minutes | Great. |
All in 15 Minutes | Hot Dang! |
20x20
500x500
10x10
colorMode()
50x50
, adjust scatter to fill.+
marks at random locations.+
a random color.noise()
to visualize its values.dist()
sin()
to create a repeating black to red to black color wave.128x128
image and set the blue value of each pixel to (y&x) * 16
Let’s look at the example above in depth:
First we need to load an image to read pixel data from.
Line 3 declares a variable to hold our image.
Line 5 begins the preload()
function. Use this function to load assets.
Line 6 loads the image.
With our image in hand we can process the pixels.
Lines 18 + 19 sets up a loop like in the writing examples above.
Line 20 uses get()
to load the color data of the current pixel. get()
returns an array like [255, 0, 0, 255]
. That would be a red, fully alpha’d color.
Lines 22, 23, 24 accesses the red, blue, and green parts of the color.
Line 25 codereates the new color for the pixel by multiplying the current color values with a random 0-1 value.
Line 27 updates the pixel in the image data.
Line 28 uses updatePixels()
to tell the image there has been an update. We didn’t need to do this in every pass through the loop when we were just setting pixels, but here we mix set and get and it appears this is now needed. This might be a bug in p5.js.
Explore using p5’s pixel manipulation functions by modifying the scripts above. Work through the following challenges in order. Don’t skip any.
Time | Comment |
---|---|
< 10 in 20 Minutes | You need to put in some extra work to strengthen your programming understanding. |
10 in 20 Minutes | Good. |
All in 20 Minutes | Great. |
All in 15 Minutes | Hot Dang! |
>
.!=
.out_color
to an average of the two color samples.out_color
to the average of this_color
and below_color
.worldImage.set(x, y, out_color);
to worldImage.set(x, y+1, out_color);
.When accessing the pixel data of the canvas itself, you need to consider the pixel density p5 is using. By default p5 will create a 2x resolution canvas when running on a high-dpi (retina) display. You can call pixelDensity(1)
to disable this feature. If you don’t, you’ll need to take into account the density when calculating a position in the pixels[]
array.
The examples on this page work with the pixels of images instead of the canvas to avoid this issue all together.
The built-in p5 someImage.get(x, y)
function gets the RGBA values of a pixel in an image. As noted in the reference, the get call is slower than accessing the values in the .pixels
array directly. In fact, get()
can be 1000s of times slower. You can use the following function to grab the pixel values more quickly.
// find the RGBA values of the pixel at x, y in the img.pixels array
// use instead of p5s built in .get(x,y), for much better performance (more than 1000x better in many cases)
// see: http://p5js.org/reference/#/p5/pixels[]
// we don't need to worry about screen pixel density here, because we are not reading from the screen
function getQuick(img, x, y) {
var i = (y * img.width + x) * 4;
return [
testImage.pixels[i],
testImage.pixels[i+1],
testImage.pixels[i+2],
testImage.pixels[i+3],
];
}
Copy the getQuick()
function above into your sketch. You can then replace a built in p5 get
call with a call to getQuick
:
c = img.get(x, y);
becomes
c = getQuick(img, x, y);