Skip to content

Commit 911f81e

Browse files
committed
updated example previews
1 parent d80df42 commit 911f81e

218 files changed

Lines changed: 9720 additions & 331 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
25.2 KB
Binary file not shown.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* Blur.
3+
*
4+
* This program analyzes every pixel in an image and blends it with the
5+
* neighboring pixels to blur the image.
6+
*
7+
* This is an example of an "image convolution" using a kernel (small matrix)
8+
* to analyze and transform a pixel based on the values of its neighbors.
9+
*
10+
* Image blur is also called a "low-pass filter". Pixels of low frequency
11+
* change (similar brightness as neighbors) are left mostly unchanged, while
12+
* those with high frequency change (sharply different values) are smoothed
13+
* out.
14+
*
15+
* The kernel here is a Box Blur, in which all components are equally valued.
16+
* Another common blur is "Gaussian Blur", in which pixels nearer the center
17+
* of the kernel have more weight than those further away.
18+
*/
19+
20+
float v = 1.0 / 9.0;
21+
float kernel[3][3] = {{ v, v, v },
22+
{ v, v, v },
23+
{ v, v, v }};
24+
25+
PImage* img;
26+
27+
void setup() {
28+
size(640, 360);
29+
img = loadImage("moon.jpg"); // Load the original image
30+
noLoop();
31+
}
32+
33+
void draw() {
34+
image(img, 0, 0); // Displays the image from point (0,0)
35+
img->loadPixels();
36+
37+
// Create an opaque image of the same size as the original
38+
PImage* blurImg = createImage(img->width, img->height, RGB);
39+
40+
// Loop through every pixel in the image
41+
for (int y = 1; y < img->height - 1; y++) { // Skip top and bottom edges
42+
for (int x = 1; x < img->width - 1; x++) { // Skip left and right edges
43+
float sumRed = 0; // Kernel sums for this pixel
44+
float sumGreen = 0;
45+
float sumBlue = 0;
46+
for (int ky = -1; ky <= 1; ky++) {
47+
for (int kx = -1; kx <= 1; kx++) {
48+
// Calculate the adjacent pixel for this kernel point
49+
int pos = (y + ky) * img->width + (x + kx);
50+
51+
// Process each channel separately, Red first.
52+
float valRed = red(img->pixels[pos]);
53+
// Multiply adjacent pixels based on the kernel values
54+
sumRed += kernel[ky + 1][kx + 1] * valRed;
55+
56+
// Green
57+
float valGreen = green(img->pixels[pos]);
58+
sumGreen += kernel[ky + 1][kx + 1] * valGreen;
59+
60+
// Blue
61+
float valBlue = blue(img->pixels[pos]);
62+
sumBlue += kernel[ky + 1][kx + 1] * valBlue;
63+
}
64+
}
65+
// For this pixel in the new image, set the output value
66+
// based on the sum from the kernel
67+
blurImg->pixels[y * blurImg->width + x] = color(sumRed, sumGreen, sumBlue);
68+
}
69+
}
70+
// State that there are changes to blurImg->pixels[]
71+
blurImg->updatePixels();
72+
73+
image(blurImg, width / 2, 0); // Draw the new image
74+
}
59.1 KB
Loading
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* Brightness Pixels
3+
* by Daniel Shiffman.
4+
*
5+
* This program adjusts the brightness of a part of the image by
6+
* calculating the distance of each pixel to the mouse.
7+
*/
8+
9+
PImage* img;
10+
11+
void setup() {
12+
size(640, 360);
13+
frameRate(30);
14+
img = loadImage("moon-wide.jpg");
15+
img->loadPixels();
16+
// Only need to load the pixels[] array once, because we're only
17+
// manipulating pixels[] inside draw(), not drawing shapes.
18+
loadPixels();
19+
}
20+
21+
void draw() {
22+
for (int x = 0; x < img->width; x++) {
23+
for (int y = 0; y < img->height; y++) {
24+
// Calculate the 1D location from a 2D grid
25+
int loc = x + y * img->width;
26+
// Get the R,G,B values from image
27+
float r, g, b;
28+
r = red(img->pixels[loc]);
29+
//g = green(img->pixels[loc]);
30+
//b = blue(img->pixels[loc]);
31+
// Calculate an amount to change brightness based on proximity to the mouse
32+
float maxdist = 50; //dist(0,0,width,height);
33+
float d = dist(x, y, mouseX, mouseY);
34+
float adjustbrightness = 255 * (maxdist - d) / maxdist;
35+
r += adjustbrightness;
36+
//g += adjustbrightness;
37+
//b += adjustbrightness;
38+
// Constrain RGB to make sure they are within 0-255 color range
39+
r = constrain(r, 0, 255);
40+
//g = constrain(g, 0, 255);
41+
//b = constrain(b, 0, 255);
42+
// Make a new color and set pixel in the window
43+
//color c = color(r, g, b);
44+
color c = color(r);
45+
pixels[y * width + x] = c;
46+
}
47+
}
48+
updatePixels();
49+
}
168 KB
Loading
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/**
2+
* Convolution
3+
* by Daniel Shiffman.
4+
*
5+
* Applies a convolution matrix to a portion of an image. Move mouse to
6+
* apply filter to different parts of the image. Click mouse to cycle
7+
* through different effects (kernels).
8+
*/
9+
10+
PImage* img;
11+
int effect = 0;
12+
int w = 120;
13+
14+
// It's possible to convolve the image with many different
15+
// matrices to produce different effects. Here are some
16+
// example kernels to try.
17+
float identity[3][3] = { { 0, 0, 0 },
18+
{ 0, 1, 0 },
19+
{ 0, 0, 0 } };
20+
21+
float darken[3][3] = { { 0, 0, 0 },
22+
{ 0, 0.5, 0 },
23+
{ 0, 0, 0 } };
24+
25+
float lighten[3][3] = { { 0, 0, 0 },
26+
{ 0, 2, 0 },
27+
{ 0, 0, 0 } };
28+
29+
float sharpen[3][3] = { { 0, -1, 0 },
30+
{ -1, 5, -1 },
31+
{ 0, -1, 0 } };
32+
33+
float sharpen2[3][3] = { { -1, -1, -1 },
34+
{ -1, 9, -1 },
35+
{ -1, -1, -1 } };
36+
37+
float box_blur[3][3] = { { 1.0/9.0, 1.0/9.0, 1.0/9.0 },
38+
{ 1.0/9.0, 1.0/9.0, 1.0/9.0 },
39+
{ 1.0/9.0, 1.0/9.0, 1.0/9.0 } };
40+
41+
float edge_det[3][3] = { { 0, 1, 0 },
42+
{ 1, -4, 1 },
43+
{ 0, 1, 0 } };
44+
45+
float emboss[3][3] = { { -2, -1, 0 },
46+
{ -1, 1, 1 },
47+
{ 0, 1, 2 } };
48+
49+
// Arrays can't hold other arrays by value, so this is an
50+
// array of pointers to 3x3 float arrays. Kept as raw arrays
51+
// (not Array<T>) deliberately: convolution() below is a per-pixel
52+
// hot loop, and this avoids the extra bounds-checked vector
53+
// indirection Array<Array<float>> would add for no real benefit here.
54+
float (*kernels[8])[3] = {
55+
identity,
56+
darken,
57+
lighten,
58+
sharpen,
59+
sharpen2,
60+
box_blur,
61+
edge_det,
62+
emboss
63+
};
64+
65+
Array<String> effect_names = {
66+
String("Identity (no change)"),
67+
String("Darken"),
68+
String("Lighten"),
69+
String("Sharpen"),
70+
String("Sharpen More"),
71+
String("Box Blur"),
72+
String("Edge Detect"),
73+
String("Emboss")
74+
};
75+
76+
void setup() {
77+
size(640, 360);
78+
img = loadImage("moon-wide.jpg");
79+
80+
noLoop();
81+
}
82+
83+
// Clicking the mouse advances to the next effect
84+
void mousePressed() {
85+
effect++;
86+
if (effect >= 8) effect = 0;
87+
88+
redraw();
89+
}
90+
91+
// Moving the mouse triggers a screen redraw
92+
void mouseMoved() {
93+
redraw();
94+
}
95+
96+
void mouseDragged() {
97+
redraw();
98+
}
99+
100+
void draw() {
101+
// We're only going to process a portion of the image
102+
// so let's set the whole image as the background first
103+
image(img, 0, 0);
104+
105+
// Calculate the small rectangle we will process
106+
int xstart = constrain(mouseX - w/2, 0, img->width);
107+
int ystart = constrain(mouseY - w/2, 0, img->height);
108+
int xend = constrain(mouseX + w/2, 0, img->width);
109+
int yend = constrain(mouseY + w/2, 0, img->height);
110+
int matrixsize = 3;
111+
loadPixels();
112+
for (int x = xstart; x < xend; x++) {
113+
for (int y = ystart; y < yend; y++ ) {
114+
color c = convolution(x, y, kernels[effect], matrixsize, img);
115+
int loc = x + y*img->width;
116+
pixels[loc] = c;
117+
}
118+
}
119+
updatePixels();
120+
121+
textSize(24);
122+
text(effect_names[effect], 4, 24);
123+
}
124+
125+
color convolution(int x, int y, float matrix[3][3], int matrixsize, PImage* img) {
126+
float rtotal = 0.0;
127+
float gtotal = 0.0;
128+
float btotal = 0.0;
129+
int offset = matrixsize / 2;
130+
for (int i = 0; i < matrixsize; i++){
131+
for (int j= 0; j < matrixsize; j++){
132+
int xloc = x+i-offset;
133+
int yloc = y+j-offset;
134+
int loc = xloc + img->width*yloc;
135+
// img->pixels is a std::vector<unsigned int>, so .size() gives
136+
// the real element count -- the faithful translation of Java's
137+
// img.pixels.length.
138+
loc = constrain(loc, 0, (int)img->pixels.size() - 1);
139+
rtotal += (red(img->pixels[loc]) * matrix[i][j]);
140+
gtotal += (green(img->pixels[loc]) * matrix[i][j]);
141+
btotal += (blue(img->pixels[loc]) * matrix[i][j]);
142+
}
143+
}
144+
rtotal = constrain(rtotal, 0, 255);
145+
gtotal = constrain(gtotal, 0, 255);
146+
btotal = constrain(btotal, 0, 255);
147+
return color(rtotal, gtotal, btotal);
148+
}
168 KB
Loading
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* Edge Detection.
3+
*
4+
* This program analyzes every pixel in an image and compares it with the
5+
* neighboring pixels to identify edges.
6+
*
7+
* This is an example of an "image convolution" using a kernel (small matrix)
8+
* to analyze and transform a pixel based on the values of its neighbors.
9+
*
10+
* This kernel describes a "Laplacian Edge Detector". It is effective,
11+
* but sensitive to noise. One common enhancement is to add a Gaussian
12+
* blur to the source image first, as in
13+
* grayImg->filter(BLUR);
14+
* to reduce impact of noise on the output. The combination is often called
15+
* "Laplace of Gaussian", or "LoG" for short.
16+
*
17+
* For weaker detection effect, try this kernel: [ 0 -1 0 ]
18+
* [ -1 4 -1 ]
19+
* [ 0 -1 0 ]
20+
*/
21+
22+
float kernel[3][3] = {{ -1, -1, -1},
23+
{ -1, 8, -1},
24+
{ -1, -1, -1}};
25+
26+
PImage* img;
27+
28+
void setup() {
29+
size(640, 360);
30+
img = loadImage("moon.jpg"); // Load the original image
31+
noLoop();
32+
}
33+
34+
void draw() {
35+
image(img, 0, 0); // Displays the image from point (0,0)
36+
img->loadPixels();
37+
38+
// Edge detection should be done on a grayscale image.
39+
// Create a copy of the source image, and convert to gray.
40+
// PImage's copy CONSTRUCTOR is deleted (see E0002 in Processing.h --
41+
// it owns a GPU texture, so value-style copying isn't supported), but
42+
// PImage::copy() is a real method that duplicates the whole image into
43+
// an independent PImage. It returns by value, so wrap it in `new` to
44+
// fit this codebase's PImage* convention -- the move constructor
45+
// handles the transfer, no pixel data is copied twice.
46+
PImage* grayImg = new PImage(img->copy());
47+
grayImg->filter(GRAY);
48+
// grayImg->filter(BLUR);
49+
50+
// Create an opaque image of the same size as the original
51+
PImage* edgeImg = createImage(grayImg->width, grayImg->height, RGB);
52+
53+
// Loop through every pixel in the image
54+
for (int y = 1; y < grayImg->height - 1; y++) { // Skip top and bottom edges
55+
for (int x = 1; x < grayImg->width - 1; x++) { // Skip left and right edges
56+
// Output of this filter is shown as offset from 50% gray.
57+
// This preserves transitions from low (dark) to high (light) value.
58+
// Starting from zero will show only high edges on black instead.
59+
float sum = 128;
60+
for (int ky = -1; ky <= 1; ky++) {
61+
for (int kx = -1; kx <= 1; kx++) {
62+
// Calculate the adjacent pixel for this kernel point
63+
int pos = (y + ky) * grayImg->width + (x + kx);
64+
65+
// Image is grayscale, red/green/blue are identical
66+
float val = blue(grayImg->pixels[pos]);
67+
// Multiply adjacent pixels based on the kernel values
68+
sum += kernel[ky + 1][kx + 1] * val;
69+
}
70+
}
71+
// For this pixel in the new image, set the output value
72+
// based on the sum from the kernel
73+
edgeImg->pixels[y * edgeImg->width + x] = color(sum);
74+
}
75+
}
76+
// State that there are changes to edgeImg->pixels[]
77+
edgeImg->updatePixels();
78+
79+
image(edgeImg, width / 2, 0); // Draw the new image
80+
}
59.1 KB
Loading
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* Histogram.
3+
*
4+
* Calculates the histogram of an image.
5+
* A histogram is the frequency distribution
6+
* of the gray levels with the number of pure black values
7+
* displayed on the left and number of pure white values on the right.
8+
*
9+
* Note that this sketch will behave differently on Android,
10+
* since most images will no longer be full 24-bit color.
11+
*/
12+
13+
size(640, 360);
14+
15+
// Load an image from the data directory
16+
// Load a different image by modifying the comments
17+
PImage* img = loadImage("frontier.jpg");
18+
image(img, 0, 0);
19+
IntList hist(256); // 256 zero-initialized entries, matching Java's "new int[256]"
20+
21+
// Calculate the histogram
22+
for (int i = 0; i < img->width; i++) {
23+
for (int j = 0; j < img->height; j++) {
24+
int bright = int(brightness(get(i, j)));
25+
hist[bright]++;
26+
}
27+
}
28+
29+
// Find the largest value in the histogram
30+
int histMax = hist.max();
31+
32+
stroke(255);
33+
// Draw half of the histogram (skip every second value)
34+
for (int i = 0; i < img->width; i += 2) {
35+
// Map i (from 0..img.width) to a location in the histogram (0..255)
36+
int which = int(map(i, 0, img->width, 0, 255));
37+
// Convert the histogram value to a location between
38+
// the bottom and the top of the picture
39+
int y = int(map(hist[which], 0, histMax, img->height, 0));
40+
line(i, img->height, i, y);
41+
}

0 commit comments

Comments
 (0)