Below is the syntax highlighted version of StdPicture.java.
/****************************************************************************** * Compilation: javac StdPicture.java * Execution: java StdPicture filename.jpg * Dependencies: Picture.java * ******************************************************************************/ package edu.princeton.cs.algs4; /** * The {@code StdPicture} class provides static methods for manipulating * the individual pixels of an image using the RGB color model. * You can either initialize a blank image (of a given dimension) or read an * image in a supported file format (typically JPEG, PNG, GIF, TIFF, and BMP). * This class also includes methods for displaying the image in a window * and saving it to a file. * * <p> * <b>Use in the curriculum.</b> * The {@code StdPicture} class is intended for early usage in the * curriculum, before objects. * The {@link Picture} class is an object-oriented version that supports * manipulating multiple pictures at the same time. * * <p> * <b>Getting started.</b> * To use this class, you must have {@code StdPicture} in your Java classpath. * Here are three possible ways to do this: * <ul> * <li> If you ran our autoinstaller, use the commands * {@code javac-introcs} and {@code java-introcs} (or {@code javac-algs4} * and {@code java-algs4}) when compiling and executing. These commands * add {@code stdlib.jar} (or {@code algs4.jar}) to the Java classpath, which * provides access to {@code StdPicture}. * * <li> Download <a href = "https://introcs.cs.princeton.edu/java/code/stdlib.jar">stdlib.jar</a> * (or <a href = "https://algs4.cs.princeton.edu/code/algs4.jar">algs4.jar</a>) * and add it to the Java classpath. * * <li> Download <a href = "https://introcs.cs.princeton.edu/java/stdlib/StdPicture.java">StdPicture.java</a> * and * <a href = "https://introcs.cs.princeton.edu/java/stdlib/Picture.java">Picture.java</a> * and put them in the working directory. * </ul> * * <p> * As a test, cut-and-paste the following short program into your editor: * <pre> * public class TestStdPicture { * public static void main(String[] args) { * StdPicture.read("https://introcs.cs.princeton.edu/java/stdlib/mandrill.jpg"); * StdPicture.show(); * } * } * </pre> * <p> * If you compile and execute the program, you should see a picture of a mandrill * (a colorful monkey native to west-central Africa) in a window. * * <p> * <b>Anatomy of an image.</b> * An image is a <em>width</em>-by-<em>height</em> grid of pixels, with pixel (0, 0) * in the upper-left corner. * Each pixel has a color that is represented using the <em>RGB color model</em>, * which specifies the levels of <em>red</em> (R), <em>green</em> (G), and <em>blue</em> (B) * on an integer scale from 0 to 255. * * <blockquote> * <img src = "https://introcs.cs.princeton.edu/java/stdlib/AnatomyImage.png" width = 200 alt = "anatomy of an image"> * </blockquote> * * <p> * <b>Initializing the picture.</b> * You can use the following methods to initialize the picture: * <ul> * <li> {@link #read(String filename)} * <li> {@link #init(int width, int height)} * </ul> * <p> * The first method reads an image in a supported file format * (typically JPEG, PNG, GIF, TIFF, and BMP) * and initializes the picture to that image. * The second method initializes a <em>width</em>-by-<em>height</em> * picture, with each pixel black. * * <p> * <b>Getting and setting the colors of the individual pixels.</b> * You can use the following methods to retrieve the RGB components * of a specified pixel: * <ul> * <li> {@link #getRed(int col, int row)} * <li> {@link #getGreen(int col, int row)} * <li> {@link #getBlue(int col, int row)} * <li> {@link #setRGB(int col, int row, int r, int g, int b)} * </ul> * <p> * The first three methods return the red, green, and blue components of pixel * (<em>col</em>, <em>row</em>). Each component is an integer between 0 and 255, * with 0 corresponding to the absence of that component and 255 corresponding * to full intensity of that component. * The last method sets the red, green, and blue components of pixel * (<em>col</em>, <em>row</em>) to the specified values. * * <p><b>Iterating over the pixels.</b> * A common operation in image processing is to iterate over and process * all of the pixels in an image. * Here is a prototypical example that converts a color image * to grayscale, using the NTSC formula * <em>Y</em> = 0.299<em>r</em> + 0.587<em>g</em> + 0.114<em>b</em>. * Note that if the red, green, and blue components are all equal, * then the color is a shade of gray. * <pre> * StdPicture.read("https://introcs.cs.princeton.edu/java/stdlib/mandrill.jpg"); * for (int col = 0; col < StdPicture.width(); col++) { * for (int row = 0; row < StdPicture.height(); row++) { * int r = StdPicture.getRed(col, row); * int g = StdPicture.getGreen(col, row); * int b = StdPicture.getBlue(col, row); * int y = (int) (Math.round(0.299*r + 0.587*g + 0.114*b)); * StdPicture.setRGB(col, row, y, y, y); * } * } * StdPicture.show(); * </pre> * * <p><b>Transparency.</b> * The {@code StdPicture} class supports transparent images, using the * ARGB color model. The following methods are useful for this: * <ul> * <li> {@link #getAlpha(int col, int row)} * <li> {@link #setARGB(int col, int row, int a, int r, int g, int b)} * </ul> * <p> * The first method gets the alpha component of pixel (<em>col</em>, <em>row</em>). * The second methods sets the alpha, red, green, and bluecomponents of * pixel (<em>col</em>, <em>row</em>). * The alpha value defines the transparency of a color, with 0 corresponding to * completely transparent and 255 to completely opaque. If transparency is not * explicitly used, the alpha value is 255. * * <p><b>Saving files.</b> * The {@code StdPicture} class supports writing images to a supported * file format (typically JPEG, PNG, GIF, TIFF, and BMP). * You can save the picture to a file two method: * <ul> * <li> {@link #save(String filename)} * </ul> * * <p>Alternatively, you can save the picture interactively * by using the menu option <em>File → Save</em> from the picture window. * * <p><b>File formats.</b> * The {@code StdPicture} class supports reading and writing images to any of the * file formats supported by {@link javax.imageio} (typically JPEG, PNG, * GIF, TIFF, and BMP). * The file extensions corresponding to JPEG, PNG, GIF, TIFF, and BMP, * are {@code .jpg}, {@code .png}, {@code .gif}, {@code .tif}, * and {@code .bmp}, respectively. * The file formats JPEG and BMP do not support transparency. * * <p><b>Memory usage.</b> * A <em>W</em>-by-<em>H</em> picture uses ~ 4 <em>W H</em> bytes of memory, * since the color of each pixel is encoded as a 32-bit <code>int</code>. * * <p><b>Additional documentation.</b> * For additional documentation, see * <a href="https://introcs.cs.princeton.edu/31datatype">Section 3.1</a> of * <i>Computer Science: An Interdisciplinary Approach</i> * by Robert Sedgewick and Kevin Wayne. * * @author Robert Sedgewick * @author Kevin Wayne */ public final class StdPicture { // the default picture width and height private static final int DEFAULT_SIZE = 512; // the underlying picture private static Picture picture = new Picture(DEFAULT_SIZE, DEFAULT_SIZE); // singleton pattern: client can't instantiate private StdPicture() { } /** * Initializes a {@code width}-by-{@code height} picture, with {@code width} columns * and {@code height} rows, where each pixel is black. * * @param width the width of the picture * @param height the height of the picture * @throws IllegalArgumentException if {@code width} is negative or zero * @throws IllegalArgumentException if {@code height} is negative or zero */ public static void init(int width, int height) { if (picture.isVisible()) { hide(); picture = new Picture(width, height); show(); } else { picture = new Picture(width, height); } } /** * Initializes the picture by reading a JPEG, PNG, GIF, BMP, or TIFF image * from a file or URL. * The filetype extension must be {@code .jpg}, {@code .png}, {@code .gif}, * {@code .bmp}, or {@code .tif}. * * @param filename the name of the file or URL * @throws IllegalArgumentException if cannot read image * @throws IllegalArgumentException if {@code name} is {@code null} */ public static void read(String filename) { Picture newPicture = new Picture(filename); // same dimension, so copy pixels instead of using new Picture and GUI if (newPicture.width() == picture.width() && newPicture.height() == newPicture.height()) { for (int col = 0; col < picture.width(); col++) { for (int row = 0; row < picture.height(); row++) { picture.setARGB(col, row, newPicture.getARGB(col, row)); } } } // different dimension, so need to use new Picture and GUI else if (picture.isVisible()) { hide(); picture = newPicture; show(); } // no GUI, so use the new Picture else { picture = newPicture; } } /** * Is the window containing the picture visible? * @return {@code true} if the picture is visible, and {@code false} otherwise */ public static boolean isVisible() { return picture.isVisible(); } /** * Displays the picture in a window on the screen. */ public static void show() { picture.show(); } /** * Hides the window containing the picture. */ public static void hide() { picture.hide(); } /** * Pauses for t milliseconds. This method is intended to support computer animation. * @param t number of milliseconds * @throws IllegalArgumentException if {@code t} is negative */ public static void pause(int t) { if (t < 0) throw new IllegalArgumentException("argument must be non-negative"); try { Thread.sleep(t); } catch (InterruptedException e) { System.out.println("Error sleeping"); } } /** * Returns the height of the picture. * * @return the height of the picture (in pixels) */ public static int height() { return picture.height(); } /** * Returns the width of the picture. * * @return the width of the picture (in pixels) */ public static int width() { return picture.width(); } /** * Returns the alpha component of the color of pixel ({@code col}, {@code row}). * * @param col the column index * @param row the row index * @return the alpha component of the color of pixel ({@code col}, {@code row}) * @throws IndexOutOfBoundsException unless both {@code 0 <= col < width} and {@code 0 <= row < height} */ public static int getAlpha(int col, int row) { int rgb = picture.getARGB(col, row); return (rgb >> 24) & 0xFF; } /** * Returns the red component of the color of pixel ({@code col}, {@code row}). * * @param col the column index * @param row the row index * @return the red component of the color of pixel ({@code col}, {@code row}) * @throws IndexOutOfBoundsException unless both {@code 0 <= col < width} and {@code 0 <= row < height} */ public static int getRed(int col, int row) { int rgb = picture.getARGB(col, row); return (rgb >> 16) & 0xFF; } /** * Returns the green component of the color of pixel ({@code col}, {@code row}). * * @param col the column index * @param row the row index * @return the green component of the color of pixel ({@code col}, {@code row}) * @throws IndexOutOfBoundsException unless both {@code 0 <= col < width} and {@code 0 <= row < height} */ public static int getGreen(int col, int row) { int rgb = picture.getARGB(col, row); return (rgb >> 8) & 0xFF; } /** * Returns the blue component of the color of pixel ({@code col}, {@code row}). * * @param col the column index * @param row the row index * @return the blue component of the color of pixel ({@code col}, {@code row}) * @throws IndexOutOfBoundsException unless both {@code 0 <= col < width} and {@code 0 <= row < height} */ public static int getBlue(int col, int row) { int rgb = picture.getARGB(col, row); return (rgb >> 0) & 0xFF; } /** * Returns the ARGB color of pixel ({@code col}, {@code row}). * * @param col the column index * @param row the row index * @return the ARGB color of pixel ({@code col}, {@code row} as a 32-bit integer * @throws IndexOutOfBoundsException unless both {@code 0 <= col < width} and {@code 0 <= row < height} */ public static int getARGB(int col, int row) { int argb = picture.getARGB(col, row); return argb; } /** * Sets the color of pixel ({@code col}, {@code row}) to the given RGB color using * red, green, and blue components. The alpha component is set to 255 (no transparency). * * @param col the column index * @param row the row index * @param r the red component of the color * @param g the green component of the color * @param b the blue component of the color * @throws IndexOutOfBoundsException unless both {@code 0 <= col < width} and {@code 0 <= row < height} * @throws IllegalArgumentException unless {@code 0 <= r < 256}, {@code 0 <= g < 256}, * and {@code 0 <= b < 256}. */ public static void setRGB(int col, int row, int r, int g, int b) { validateComponent(r, "red"); validateComponent(g, "green"); validateComponent(b, "blue"); int a = 255; int argb = (a << 24) | (r << 16) | (g << 8) | (b << 0); picture.setARGB(col, row, argb); } /** * Sets the color of pixel ({@code col}, {@code row}) to the given ARGB color using * alpha, red, green, and blue components. * * @param col the column index * @param row the row index * @param a the alpha component of the color * @param r the red component of the color * @param g the green component of the color * @param b the blue component of the color * @throws IndexOutOfBoundsException unless both {@code 0 <= col < width} and {@code 0 <= row < height} * @throws IllegalArgumentException unless {@code 0 <= a < 256}, {@code 0 <= r < 256}, * {@code 0 <= g < 256}, and {@code 0 <= b < 256}. */ public static void setARGB(int col, int row, int a, int r, int g, int b) { validateComponent(a, "alpha"); validateComponent(r, "red"); validateComponent(g, "green"); validateComponent(b, "blue"); // internally represented using ARGB, not RGBA int argb = (a << 24) | (r << 16) | (g << 8) | (b << 0); picture.setARGB(col, row, argb); } /** * Sets the color of pixel ({@code col}, {@code row}) to the given RGB color. * * @param col the column index * @param row the row index * @param rgb the RGB color, represented as a 24-bit integer * @throws IndexOutOfBoundsException unless both {@code 0 <= col < width} and {@code 0 <= row < height} * @throws IllegalArgumentException unless {@code 0 <= rgb < 2^24}. */ /* public static void setRGB(int col, int row, int rgb) { int a = 255; int argb = (a << 24) | (rgb); picture.setARGB(col, row, argb); } */ /** * Sets the color of pixel ({@code col}, {@code row}) to the given ARGB color. * * @param col the column index * @param row the row index * @param argb the ARGB color, represented as a 32-bit integer * @throws IndexOutOfBoundsException unless both {@code 0 <= col < width} and {@code 0 <= row < height} */ public static void setARGB(int col, int row, int argb) { picture.setARGB(col, row, argb); } /** * Sets the title of this picture. * @param title the title * @throws IllegalArgumentException if {@code title} is {@code null} */ public static void setTitle(String title) { picture.setTitle(title); } /** * Saves the picture to a file in a supported file format * (typically JPEG, PNG, GIF, TIFF, and BMP). * The filetype extension must be {@code .jpg}, {@code .png}, {@code .gif}, * {@code .bmp}, or {@code .tif}. * If the file format does not support transparency (such as JPEG * or BMP), it will be converted to be opaque (with purely * transparent pixels converted to black). * * @param filename the name of the file * @throws IllegalArgumentException if {@code filename} is {@code null} * @throws IllegalArgumentException if {@code filename} is the empty string */ public static void save(String filename) { picture.save(filename); } private static void validateComponent(int val, String name) { if (val < 0 || val >= 256) { throw new IllegalArgumentException(name + " must be between 0 and 255"); } } /** * Unit tests this {@code StdPicture} data type. * Reads a picture specified by the command-line argument, * and shows it in a window on the screen. * * @param args the command-line arguments */ public static void main(String[] args) { StdPicture.read(args[0]); System.out.printf("%d-by-%d\n", picture.width(), picture.height()); StdPicture.show(); } } /****************************************************************************** * Copyright 2002-2022, Robert Sedgewick and Kevin Wayne. * * This file is part of algs4.jar, which accompanies the textbook * * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne, * Addison-Wesley Professional, 2011, ISBN 0-321-57351-X. * http://algs4.cs.princeton.edu * * * algs4.jar is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * algs4.jar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with algs4.jar. If not, see http://www.gnu.org/licenses. ******************************************************************************/