Skip to content

Commit c858cf4

Browse files
authored
Merge pull request #6424 from nickmcintyre/sod-image
Edit docs for image
2 parents df56c80 + fbae8ec commit c858cf4

File tree

1 file changed

+154
-94
lines changed

1 file changed

+154
-94
lines changed

src/image/image.js

Lines changed: 154 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -13,125 +13,157 @@ import p5 from '../core/main';
1313
import omggif from 'omggif';
1414

1515
/**
16-
* Creates a new <a href="#/p5.Image">p5.Image</a> (the datatype for storing images). This provides a
17-
* fresh buffer of pixels to play with. Set the size of the buffer with the
18-
* width and height parameters.
16+
* Creates a new <a href="#/p5.Image">p5.Image</a> object. The new image is
17+
* transparent by default.
1918
*
20-
* .<a href="#/p5.Image/pixels">pixels</a> gives access to an array containing the values for all the pixels
21-
* in the display window.
22-
* These values are numbers. This array is the size (including an appropriate
23-
* factor for the <a href="#/p5/pixelDensity">pixelDensity</a>) of the display window x4,
24-
* representing the R, G, B, A values in order for each pixel, moving from
25-
* left to right across each row, then down each column. See .<a href="#/p5.Image/pixels">pixels</a> for
26-
* more info. It may also be simpler to use <a href="#/p5.Image/set">set()</a> or <a href="#/p5.Image/get">get()</a>.
27-
*
28-
* Before accessing the pixels of an image, the data must loaded with the
29-
* <a href="#/p5.Image/loadPixels">loadPixels()</a> function. After the array data has been modified, the
30-
* <a href="#/p5.Image/updatePixels">updatePixels()</a> function must be run to update the changes.
19+
* `createImage()` uses the `width` and `height` paremeters to set the new
20+
* <a href="#/p5.Image">p5.Image</a> object's dimensions in pixels. The new
21+
* <a href="#/p5.Image">p5.Image</a> can be modified by updating its
22+
* <a href="#/p5.Image/pixels">pixels</a> array or by calling its
23+
* <a href="#/p5.Image/get">get()</a> and
24+
* <a href="#/p5.Image/set">set()</a> methods. The
25+
* <a href="#/p5.Image/loadPixels">loadPixels()</a> method must be called
26+
* before reading or modifying pixel values. The
27+
* <a href="#/p5.Image/updatePixels">updatePixels()</a> method must be called
28+
* for updates to take effect.
3129
*
3230
* @method createImage
33-
* @param {Integer} width width in pixels
34-
* @param {Integer} height height in pixels
35-
* @return {p5.Image} the <a href="#/p5.Image">p5.Image</a> object
31+
* @param {Integer} width width in pixels.
32+
* @param {Integer} height height in pixels.
33+
* @return {p5.Image} new <a href="#/p5.Image">p5.Image</a> object.
3634
* @example
3735
* <div>
3836
* <code>
3937
* let img = createImage(66, 66);
4038
* img.loadPixels();
41-
* for (let i = 0; i < img.width; i++) {
42-
* for (let j = 0; j < img.height; j++) {
43-
* img.set(i, j, color(0, 90, 102));
39+
* for (let x = 0; x < img.width; x += 1) {
40+
* for (let y = 0; y < img.height; y += 1) {
41+
* img.set(x, y, 0);
4442
* }
4543
* }
4644
* img.updatePixels();
4745
* image(img, 17, 17);
46+
*
47+
* describe('A black square drawn in the middle of a gray square.');
4848
* </code>
4949
* </div>
5050
*
5151
* <div>
5252
* <code>
5353
* let img = createImage(66, 66);
5454
* img.loadPixels();
55-
* for (let i = 0; i < img.width; i++) {
56-
* for (let j = 0; j < img.height; j++) {
57-
* img.set(i, j, color(0, 90, 102, (i % img.width) * 2));
55+
* for (let x = 0; x < img.width; x += 1) {
56+
* for (let y = 0; y < img.height; y += 1) {
57+
* let a = map(x, 0, img.width, 0, 255);
58+
* let c = color(0, a);
59+
* img.set(x, y, c);
5860
* }
5961
* }
6062
* img.updatePixels();
6163
* image(img, 17, 17);
62-
* image(img, 34, 34);
64+
*
65+
* describe('A square with a horizontal color gradient that transitions from gray to black.');
6366
* </code>
6467
* </div>
6568
*
6669
* <div>
6770
* <code>
68-
* let pink = color(255, 102, 204);
6971
* let img = createImage(66, 66);
7072
* img.loadPixels();
7173
* let d = pixelDensity();
72-
* let halfImage = 4 * (img.width * d) * (img.height / 2 * d);
74+
* let halfImage = 4 * (d * img.width) * (d * img.height / 2);
7375
* for (let i = 0; i < halfImage; i += 4) {
74-
* img.pixels[i] = red(pink);
75-
* img.pixels[i + 1] = green(pink);
76-
* img.pixels[i + 2] = blue(pink);
77-
* img.pixels[i + 3] = alpha(pink);
76+
* // Red.
77+
* img.pixels[i] = 0;
78+
* // Green.
79+
* img.pixels[i + 1] = 0;
80+
* // Blue.
81+
* img.pixels[i + 2] = 0;
82+
* // Alpha.
83+
* img.pixels[i + 3] = 255;
7884
* }
7985
* img.updatePixels();
8086
* image(img, 17, 17);
87+
*
88+
* describe('A black square drawn in the middle of a gray square.');
8189
* </code>
8290
* </div>
83-
*
84-
* @alt
85-
* 66×66 dark turquoise rect in center of canvas.
86-
* 2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas
87-
* no image displayed
8891
*/
8992
p5.prototype.createImage = function(width, height) {
9093
p5._validateParameters('createImage', arguments);
9194
return new p5.Image(width, height);
9295
};
9396

9497
/**
95-
* Save the current canvas as an image. The browser will either save the
96-
* file immediately, or prompt the user with a dialogue window.
98+
* Saves the current canvas as an image. The browser will either save the
99+
* file immediately or prompt the user with a dialogue window.
97100
*
98101
* @method saveCanvas
99-
* @param {p5.Element|HTMLCanvasElement} selectedCanvas a variable
100-
* representing a specific html5 canvas (optional)
101-
* @param {String} [filename]
102-
* @param {String} [extension] 'jpg' or 'png'
102+
* @param {p5.Element|HTMLCanvasElement} selectedCanvas reference to a
103+
* specific HTML5 canvas element.
104+
* @param {String} [filename] file name. Defaults to 'untitled'.
105+
* @param {String} [extension] file extension, either 'jpg' or 'png'. Defaults to 'png'.
103106
*
104107
* @example
105-
* <div class='norender notest'><code>
108+
* <div class='norender'>
109+
* <code>
106110
* function setup() {
107-
* let c = createCanvas(100, 100);
108-
* background(255, 0, 0);
109-
* saveCanvas(c, 'myCanvas', 'jpg');
111+
* createCanvas(100, 100);
112+
* background(255);
113+
* saveCanvas();
110114
* }
111-
* </code></div>
112-
* <div class='norender notest'><code>
113-
* // note that this example has the same result as above
114-
* // if no canvas is specified, defaults to main canvas
115+
* </code>
116+
* </div>
117+
*
118+
* <div class='norender'>
119+
* <code>
115120
* function setup() {
116-
* let c = createCanvas(100, 100);
117-
* background(255, 0, 0);
121+
* createCanvas(100, 100);
122+
* background(255);
123+
* saveCanvas('myCanvas.jpg');
124+
* }
125+
* </code>
126+
* </div>
127+
*
128+
* <div class='norender'>
129+
* <code>
130+
* function setup() {
131+
* createCanvas(100, 100);
132+
* background(255);
118133
* saveCanvas('myCanvas', 'jpg');
134+
* }
135+
* </code>
136+
* </div>
119137
*
120-
* // all of the following are valid
121-
* saveCanvas(c, 'myCanvas', 'jpg');
122-
* saveCanvas(c, 'myCanvas.jpg');
123-
* saveCanvas(c, 'myCanvas');
124-
* saveCanvas(c);
125-
* saveCanvas('myCanvas', 'png');
126-
* saveCanvas('myCanvas');
127-
* saveCanvas();
138+
* <div class='norender'>
139+
* <code>
140+
* function setup() {
141+
* let cnv = createCanvas(100, 100);
142+
* background(255);
143+
* saveCanvas(cnv);
128144
* }
129-
* </code></div>
145+
* </code>
146+
* </div>
130147
*
131-
* @alt
132-
* no image displayed
133-
* no image displayed
134-
* no image displayed
148+
* <div class='norender'>
149+
* <code>
150+
* function setup() {
151+
* let cnv = createCanvas(100, 100);
152+
* background(255);
153+
* saveCanvas(cnv, 'myCanvas.jpg');
154+
* }
155+
* </code>
156+
* </div>
157+
*
158+
* <div class='norender'>
159+
* <code>
160+
* function setup() {
161+
* let cnv = createCanvas(100, 100);
162+
* background(255);
163+
* saveCanvas(cnv, 'myCanvas', 'jpg');
164+
* }
165+
* </code>
166+
* </div>
135167
*/
136168
/**
137169
* @method saveCanvas
@@ -413,50 +445,78 @@ p5.prototype.encodeAndDownloadGif = function(pImg, filename) {
413445
};
414446

415447
/**
416-
* Capture a sequence of frames that can be used to create a movie.
417-
* Accepts a callback. For example, you may wish to send the frames
418-
* to a server where they can be stored or converted into a movie.
419-
* If no callback is provided, the browser will pop up save dialogues in an
420-
* attempt to download all of the images that have just been created. With the
421-
* callback provided the image data isn't saved by default but instead passed
422-
* as an argument to the callback function as an array of objects, with the
423-
* size of array equal to the total number of frames.
448+
* Captures a sequence of frames from the canvas that can be used to create a
449+
* movie. Frames are downloaded as individual image files by default.
450+
*
451+
* The first parameter, `filename`, sets the prefix for the file names. For
452+
* example, setting the prefix to `'frame'` would generate the image files
453+
* `frame0.png`, `frame1.png`, and so on. The second parameter, `extension`,
454+
* sets the file type to either `'png'` or `'jpg'`.
424455
*
425-
* The arguments `duration` and `framerate` are constrained to be less or equal to 15 and 22, respectively, which means you
426-
* can only download a maximum of 15 seconds worth of frames at 22 frames per second, adding up to 330 frames.
427-
* This is done in order to avoid memory problems since a large enough canvas can fill up the memory in your computer
428-
* very easily and crash your program or even your browser.
456+
* The third parameter, `duration`, sets the duration to record in seconds.
457+
* The maximum duration is 15 seconds. The fourth parameter, `framerate`, sets
458+
* the number of frames to record per second. The maximum frame rate value is
459+
* 22. Limits are placed on `duration` and `framerate` to avoid using too much
460+
* memory. Recording large canvases can easily crash sketches or even web
461+
* browsers.
429462
*
430-
* To export longer animations, you might look into a library like
431-
* <a href="https://github.com/spite/ccapture.js/">ccapture.js</a>.
463+
* The fifth parameter, `callback`, is optional. If a function is passed,
464+
* image files won't be saved by default. The callback function can be used
465+
* to process an array containing the data for each captured frame. The array
466+
* of image data contains a sequence of objects with three properties for each
467+
* frame: `imageData`, `filename`, and `extension`.
432468
*
433-
* @method saveFrames
434-
* @param {String} filename
435-
* @param {String} extension 'jpg' or 'png'
436-
* @param {Number} duration Duration in seconds to save the frames for. This parameter will be constrained to be less or equal to 15.
437-
* @param {Number} framerate Framerate to save the frames in. This parameter will be constrained to be less or equal to 22.
438-
* @param {function(Array)} [callback] A callback function that will be executed
469+
* @method saveFrames
470+
* @param {String} filename prefix of file name.
471+
* @param {String} extension file extension, either 'jpg' or 'png'.
472+
* @param {Number} duration duration in seconds to record. This parameter will be constrained to be less or equal to 15.
473+
* @param {Number} framerate number of frames to save per second. This parameter will be constrained to be less or equal to 22.
474+
* @param {function(Array)} [callback] callback function that will be executed
439475
to handle the image data. This function
440476
should accept an array as argument. The
441477
array will contain the specified number of
442478
frames of objects. Each object has three
443-
properties: imageData - an
444-
image/octet-stream, filename and extension.
445-
* @example
446-
* <div><code>
479+
properties: `imageData`, `filename`, and `extension`.
480+
* @example
481+
* <div>
482+
* <code>
483+
* function draw() {
484+
* let r = frameCount % 255;
485+
* let g = 50;
486+
* let b = 100;
487+
* background(r, g, b);
488+
*
489+
* describe('A square repeatedly changes color from blue to pink.');
490+
* }
491+
*
492+
* function keyPressed() {
493+
* if (key === 's') {
494+
* saveFrames('frame', 'png', 1, 5);
495+
* }
496+
* }
497+
* </code>
498+
* </div>
499+
*
500+
* <div>
501+
* <code>
447502
* function draw() {
448-
* background(mouseX);
503+
* let r = frameCount % 255;
504+
* let g = 50;
505+
* let b = 100;
506+
* background(r, g, b);
507+
*
508+
* describe('A square repeatedly changes color from blue to pink.');
449509
* }
450510
*
451511
* function mousePressed() {
452-
* saveFrames('out', 'png', 1, 25, data => {
512+
* saveFrames('frame', 'png', 1, 5, data => {
513+
* // Prints an array of objects containing raw image data,
514+
* // filenames, and extensions.
453515
* print(data);
454516
* });
455517
* }
456-
</code></div>
457-
*
458-
* @alt
459-
* canvas background goes from light to dark with mouse x.
518+
* </code>
519+
* </div>
460520
*/
461521
p5.prototype.saveFrames = function(fName, ext, _duration, _fps, callback) {
462522
p5._validateParameters('saveFrames', arguments);

0 commit comments

Comments
 (0)