diff --git a/src/image/loading_displaying.js b/src/image/loading_displaying.js index 76e59cf29f..981fb589ec 100644 --- a/src/image/loading_displaying.js +++ b/src/image/loading_displaying.js @@ -16,55 +16,78 @@ import '../core/friendly_errors/file_errors'; import '../core/friendly_errors/fes_core'; /** - * Loads an image from a path and creates a p5.Image from it. + * Loads an image to create a p5.Image object. * - * The image may not be immediately available for rendering. - * If you want to ensure that the image is ready before doing - * anything with it, place the loadImage() call in preload(). - * You may also supply a callback function to handle the image when it's ready. + * `loadImage()` interprets the first parameter one of three ways. If the path + * to an image file is provided, `loadImage()` will load it. Paths to local + * files should be relative, such as `'assets/thundercat.jpg'`. URLs such as + * `'https://example.com/thundercat.jpg'` may be blocked due to browser + * security. Raw image data can also be passed as a base64 encoded image in + * the form `'data:image/png;base64,arandomsequenceofcharacters'`. * - * The path to the image should be relative to the HTML file - * that links in your sketch. Loading an image from a URL or other - * remote location may be blocked due to your browser's built-in - * security. - - * You can also pass in a string of a base64 encoded image as an alternative to the file path. - * Remember to add "data:image/png;base64," in front of the string. + * The second parameter is optional. If a function is passed, it will be + * called once the image has loaded. The callback function can optionally use + * the new p5.Image object. + * + * The third parameter is also optional. If a function is passed, it will be + * called if the image fails to load. The callback function can optionally use + * the event error. + * + * Images can take time to load. Calling `loadImage()` in + * preload() ensures images load before they're + * used in setup() or draw(). * * @method loadImage - * @param {String} path Path of the image to be loaded - * @param {function(p5.Image)} [successCallback] Function to be called once - * the image is loaded. Will be passed the - * p5.Image. - * @param {function(Event)} [failureCallback] called with event error if - * the image fails to load. - * @return {p5.Image} the p5.Image object + * @param {String} path path of the image to be loaded or base64 encoded image. + * @param {function(p5.Image)} [successCallback] function called with + * p5.Image once it + * loads. + * @param {function(Event)} [failureCallback] function called with event + * error if the image fails to load. + * @return {p5.Image} the p5.Image object. * @example *
* let img;
+ *
* function preload() {
* img = loadImage('assets/laDefense.jpg');
* }
+ *
* function setup() {
* image(img, 0, 0);
+ * describe('Image of the underside of a white umbrella and a gridded ceiling.');
* }
*
*
* function setup() {
- * // here we use a callback to display the image after loading
* loadImage('assets/laDefense.jpg', img => {
* image(img, 0, 0);
* });
+ * describe('Image of the underside of a white umbrella and a gridded ceiling.');
* }
*
*
+ * function setup() {
+ * loadImage('assets/laDefense.jpg', success, failure);
+ * }
+ *
+ * function success(img) {
+ * image(img, 0, 0);
+ * describe('Image of the underside of a white umbrella and a gridded ceiling.');
+ * }
+ *
+ * function failure(event) {
+ * console.error('Oops!', event);
+ * }
+ *
+ *
- * function setup() {
- * createCanvas(100, 100);
- * }
- *
* function draw() {
- * colorMode(RGB);
- * background(30);
- *
- * // create a bunch of circles that move in... circles!
- * for (let i = 0; i < 10; i++) {
- * let opacity = map(i, 0, 10, 0, 255);
- * noStroke();
- * fill(230, 250, 90, opacity);
- * circle(
- * 30 * sin(frameCount / (30 - i)) + width / 2,
- * 30 * cos(frameCount / (30 - i)) + height / 2,
- * 10
- * );
- * }
+ * background(200);
+ * let c = frameCount % 255;
+ * fill(c);
+ * circle(50, 50, 25);
+ *
+ * describe('A circle drawn in the middle of a gray square. The circle changes color from black to white, then repeats.');
* }
*
- * // you can put it in the mousePressed function,
- * // or keyPressed for example
* function keyPressed() {
- * // this will download the first 5 seconds of the animation!
* if (key === 's') {
* saveGif('mySketch', 5);
* }
* }
*
*
*
- * This function can also be used to draw images without distorting the orginal aspect ratio,
- * by adding 9th parameter, fit, which can either be COVER or CONTAIN.
- * CONTAIN, as the name suggests, contains the whole image within the specified destination box
- * without distorting the image ratio.
- * COVER covers the entire destination box.
+ * The fourth and fifth parameters, `dw` and `dh`, are optional. They set the
+ * the width and height to draw the destination image. By default, `image()`
+ * draws the full source image at its original size.
+ *
+ * The sixth and seventh parameters, `sx` and `sy`, are also optional.
+ * These coordinates define the top left corner of a subsection to draw from
+ * the source image.
+ *
+ * The eighth and ninth parameters, `sw` and `sh`, are also optional.
+ * They define the width and height of a subsection to draw from the source
+ * image. By default, `image()` draws the full subsection that begins at
+ * (`sx`, `sy`) and extends to the edges of the source image.
*
+ * The ninth parameter, `fit`, is also optional. It enables a subsection of
+ * the source image to be drawn without affecting its aspect ratio. If
+ * `CONTAIN` is passed, the full subsection will appear within the destination
+ * rectangle. If `COVER` is passed, the subsection will completely cover the
+ * destination rectangle. This may have the effect of zooming into the
+ * subsection.
*
+ * The tenth and eleventh paremeters, `xAlign` and `yAlign`, are also
+ * optional. They determine how to align the fitted subsection. `xAlign` can
+ * be set to either `LEFT`, `RIGHT`, or `CENTER`. `yAlign` can be set to
+ * either `TOP`, `BOTTOM`, or `CENTER`. By default, both `xAlign` and `yAlign`
+ * are set to `CENTER`.
*
* @method image
- * @param {p5.Image|p5.Element|p5.Texture|p5.Framebuffer|p5.FramebufferTexture} img the image to display
- * @param {Number} x the x-coordinate of the top-left corner of the image
- * @param {Number} y the y-coordinate of the top-left corner of the image
- * @param {Number} [width] the width to draw the image
- * @param {Number} [height] the height to draw the image
+ * @param {p5.Image|p5.Element|p5.Texture|p5.Framebuffer|p5.FramebufferTexture} img image to display.
+ * @param {Number} x x-coordinate of the top-left corner of the image.
+ * @param {Number} y y-coordinate of the top-left corner of the image.
+ * @param {Number} [width] width to draw the image.
+ * @param {Number} [height] height to draw the image.
* @example
*
* let img;
+ *
* function preload() {
* img = loadImage('assets/laDefense.jpg');
* }
+ *
* function setup() {
- * // Top-left corner of the img is at (0, 0)
- * // Width and height are the img's original width and height
+ * background(50);
* image(img, 0, 0);
+ *
+ * describe('An image of the underside of a white umbrella with a gridded ceiling above.');
* }
*
*
* let img;
+ *
* function preload() {
* img = loadImage('assets/laDefense.jpg');
* }
+ *
* function setup() {
* background(50);
- * // Top-left corner of the img is at (10, 10)
- * // Width and height are 50×50
- * image(img, 10, 10, 50, 50);
+ * image(img, 10, 10);
+ *
+ * describe('An image of the underside of a white umbrella with a gridded ceiling above. The image has dark gray borders on its left and top.');
* }
*
*
+ * let img;
+ *
+ * function preload() {
+ * img = loadImage('assets/laDefense.jpg');
+ * }
+ *
* function setup() {
- * // Here, we use a callback to display the image after loading
- * loadImage('assets/laDefense.jpg', img => {
- * image(img, 0, 0);
- * });
+ * background(50);
+ * image(img, 0, 0, 50, 50);
+ *
+ * describe('An image of the underside of a white umbrella with a gridded ceiling above. The image is drawn in the top left corner of a dark gray square.');
* }
*
*
* let img;
+ *
* function preload() {
- * img = loadImage('assets/gradient.png');
+ * img = loadImage('assets/laDefense.jpg');
* }
+ *
* function setup() {
- * // 1. Background image
- * // Top-left corner of the img is at (0, 0)
- * // Width and height are the img's original width and height, 100×100
- * image(img, 0, 0);
- * // 2. Top right image
- * // Top-left corner of destination rectangle is at (50, 0)
- * // Destination rectangle width and height are 40×20
- * // The next parameters are relative to the source image:
- * // - Starting at position (50, 50) on the source image, capture a 50×50
- * // subsection
- * // - Draw this subsection to fill the dimensions of the destination rectangle
- * image(img, 50, 0, 40, 20, 50, 50, 50, 50);
+ * background(50);
+ * image(img, 25, 25, 50, 50, 25, 25, 50, 50);
+ *
+ * describe('An image of a gridded ceiling drawn in the center of a dark gray square.');
* }
*
*
* let img;
+ *
* function preload() {
- * // dimensions of image are 780 x 440
- * // dimensions of canvas are 100 x 100
* img = loadImage('assets/moonwalk.jpg');
* }
+ *
* function setup() {
- * // CONTAIN the whole image without distorting the image's aspect ratio
- * // CONTAIN the image within the specified destination box and display at LEFT,CENTER position
- * background(color('green'));
- * image(img, 0, 0, width, height, 0, 0, img.width, img.height, CONTAIN, LEFT);
+ * background(50);
+ * image(img, 0, 0, width, height, 0, 0, img.width, img.height, CONTAIN);
+ *
+ * describe('An image of an astronaut on the moon. The top and bottom borders of the image are dark gray.');
* }
*
*
* let img;
+ *
* function preload() {
- * img = loadImage('assets/laDefense50.png'); // dimensions of image are 50 x 50
+ * // Image is 50 x 50 pixels.
+ * img = loadImage('assets/laDefense50.png');
* }
+ *
* function setup() {
- * // COVER the whole destination box without distorting the image's aspect ratio
- * // COVER the specified destination box which is of dimension 100 x 100
- * // Without specifying xAlign or yAlign, the image will be
- * // centered in the destination box in both axes
+ * background(50);
* image(img, 0, 0, width, height, 0, 0, img.width, img.height, COVER);
+ *
+ * describe('A pixelated image of the underside of a white umbrella with a gridded ceiling above.');
* }
*
*
* let img;
+ *
* function preload() {
* img = loadImage('assets/laDefense.jpg');
* }
+ *
* function setup() {
* image(img, 0, 0);
- * tint(0, 153, 204); // Tint blue
+ * tint('red');
* image(img, 50, 0);
+ *
+ * describe('Two images of an umbrella and a ceiling side-by-side. The image on the right has a red tint.');
* }
*
*
* let img;
+ *
* function preload() {
* img = loadImage('assets/laDefense.jpg');
* }
+ *
* function setup() {
* image(img, 0, 0);
- * tint(0, 153, 204, 126); // Tint blue and set transparency
+ * tint(255, 0, 0);
* image(img, 50, 0);
+ *
+ * describe('Two images of an umbrella and a ceiling side-by-side. The image on the right has a red tint.');
* }
*
*
* let img;
+ *
* function preload() {
* img = loadImage('assets/laDefense.jpg');
* }
+ *
* function setup() {
* image(img, 0, 0);
- * tint(255, 126); // Apply transparency without changing color
+ * tint(255, 0, 0, 100);
* image(img, 50, 0);
+ *
+ * describe('Two images of an umbrella and a ceiling side-by-side. The image on the right has a transparent red tint.');
* }
*
*
+ * let img;
+ *
+ * function preload() {
+ * img = loadImage('assets/laDefense.jpg');
+ * }
+ *
+ * function setup() {
+ * image(img, 0, 0);
+ * tint(255, 180);
+ * image(img, 50, 0);
+ *
+ * describe('Two images of an umbrella and a ceiling side-by-side. The image on the right is transparent.');
+ * }
+ *
+ *
* let img;
+ *
* function preload() {
- * img = loadImage('assets/bricks.jpg');
+ * img = loadImage('assets/laDefense.jpg');
* }
* function setup() {
- * tint(0, 153, 204); // Tint blue
+ * tint('red');
* image(img, 0, 0);
- * noTint(); // Disable tint
+ * noTint();
* image(img, 50, 0);
+ *
+ * describe('Two images of an umbrella and a ceiling side-by-side. The image on the left has a red tint.');
* }
*
*
* let img;
+ *
* function preload() {
* img = loadImage('assets/bricks.jpg');
* }
+ *
* function setup() {
+ * background(200);
* imageMode(CORNER);
* image(img, 10, 10, 50, 50);
+ *
+ * describe('A square image of a brick wall is drawn at the top left of a gray square.');
* }
*
*
* let img;
+ *
* function preload() {
* img = loadImage('assets/bricks.jpg');
* }
+ *
* function setup() {
+ * background(200);
* imageMode(CORNERS);
* image(img, 10, 10, 90, 40);
+ *
+ * describe('An image of a brick wall is drawn on a gray square. The image is squeezed into a small rectangular area.');
* }
*
*
* let img;
+ *
* function preload() {
* img = loadImage('assets/bricks.jpg');
* }
+ *
* function setup() {
+ * background(200);
* imageMode(CENTER);
* image(img, 50, 50, 80, 80);
+ *
+ * describe('A square image of a brick wall is drawn on a gray square.');
* }
*
*