Part of the Processing project - http://processing.org
Copyright (c) 2004-08 Ben Fry and Casey Reas
Copyright (c) 2001-04 Massachusetts Institute of Technology
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
*/
package processing.core;
import java.awt.image.*;
import java.io.*;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Set;
import javax.imageio.ImageIO;
/**
* Datatype for storing images. Processing can display <b>.gif</b>, <b>.jpg</b>, <b>.tga</b>, and <b>.png</b> images. Images may be displayed in 2D and 3D space.
* Before an image is used, it must be loaded with the <b>loadImage()</b> function.
* The <b>PImage</b> object contains fields for the <b>width</b> and <b>height</b> of the image,
* as well as an array called <b>pixels[]</b> which contains the values for every pixel in the image.
* A group of methods, described below, allow easy access to the image's pixels and alpha channel and simplify the process of compositing.
* <br><br>Before using the <b>pixels[]</b> array, be sure to use the <b>loadPixels()</b> method on the image to make sure that the pixel data is properly loaded.
* <br><br>To create a new image, use the <b>createImage()</b> function (do not use <b>new PImage()</b>).
* =advanced
*
* Storage class for pixel data. This is the base class for most image and
* pixel information, such as PGraphics and the video library classes.
* <P>
* Code for copying, resizing, scaling, and blending contributed
* Loads the pixel data for the image into its <b>pixels[]</b> array. This function must always be called before reading from or writing to <b>pixels[]</b>.
* <br><br>Certain renderers may or may not seem to require <b>loadPixels()</b> or <b>updatePixels()</b>. However, the rule is that any time you want to manipulate the <b>pixels[]</b> array, you must first call <b>loadPixels()</b>, and after changes have been made, call <b>updatePixels()</b>. Even if the renderer may not seem to use this function in the current Processing release, this will always be subject to change.
* =advanced
* Call this when you want to mess with the pixels[] array.
* <p/>
* For subclasses where the pixels[] buffer isn't set by default,
* this should copy all data into the pixels[] array
*
* @webref
* @brief Loads the pixel data for the image into its pixels[] array
*/
public void loadPixels() { // ignore
}
public void updatePixels() { // ignore
updatePixelsImpl(0, 0, width, height);
}
/**
* Updates the image with the data in its <b>pixels[]</b> array. Use in conjunction with <b>loadPixels()</b>. If you're only reading pixels from the array, there's no need to call <b>updatePixels()</b>.
* <br><br>Certain renderers may or may not seem to require <b>loadPixels()</b> or <b>updatePixels()</b>. However, the rule is that any time you want to manipulate the <b>pixels[]</b> array, you must first call <b>loadPixels()</b>, and after changes have been made, call <b>updatePixels()</b>. Even if the renderer may not seem to use this function in the current Processing release, this will always be subject to change.
* <br><br>Currently, none of the renderers use the additional parameters to <b>updatePixels()</b>, however this may be implemented in the future.
* =advanced
* Mark the pixels in this region as needing an update.
* This is not currently used by any of the renderers, however the api
* is structured this way in the hope of being able to use this to
* speed things up in the future.
* @webref
* @brief Updates the image with the data in its pixels[] array
* @param x
* @param y
* @param w
* @param h
*/
public void updatePixels(int x, int y, int w, int h) { // ignore
// if (imageMode == CORNER) { // x2, y2 are w/h
// x2 += x1;
// y2 += y1;
//
// } else if (imageMode == CENTER) {
// x1 -= x2 / 2;
// y1 -= y2 / 2;
// x2 += x1;
// y2 += y1;
// }
updatePixelsImpl(x, y, w, h);
}
protected void updatePixelsImpl(int x, int y, int w, int h) {
* Reads the color of any pixel or grabs a group of pixels. If no parameters are specified, the entire image is returned. Get the value of one pixel by specifying an x,y coordinate. Get a section of the display window by specifing an additional <b>width</b> and <b>height</b> parameter. If the pixel requested is outside of the image window, black is returned. The numbers returned are scaled according to the current color ranges, but only RGB values are returned by this function. Even though you may have drawn a shape with <b>colorMode(HSB)</b>, the numbers returned will be in RGB.
* <br><br>Getting the color of a single pixel with <b>get(x, y)</b> is easy, but not as fast as grabbing the data directly from <b>pixels[]</b>. The equivalent statement to "get(x, y)" using <b>pixels[]</b> is "pixels[y*width+x]". Processing requires calling <b>loadPixels()</b> to load the display window data into the <b>pixels[]</b> array before getting the values.
* <br><br>As of release 0149, this function ignores <b>imageMode()</b>.
*
* @webref
* @brief Reads the color of any pixel or grabs a rectangle of pixels
* Changes the color of any pixel or writes an image directly into the display window. The <b>x</b> and <b>y</b> parameters specify the pixel to change and the <b>color</b> parameter specifies the color value. The color parameter is affected by the current color mode (the default is RGB values from 0 to 255). When setting an image, the x and y parameters define the coordinates for the upper-left corner of the image.
* <br><br>Setting the color of a single pixel with <b>set(x, y)</b> is easy, but not as fast as putting the data directly into <b>pixels[]</b>. The equivalent statement to "set(x, y, #000000)" using <b>pixels[]</b> is "pixels[y*width+x] = #000000". You must call <b>loadPixels()</b> to load the display window data into the <b>pixels[]</b> array before setting the values and calling <b>updatePixels()</b> to update the window with any changes.
* <br><br>As of release 1.0, this function ignores <b>imageMode()</b>.
* <br><br>Due to what appears to be a bug in Apple's Java implementation, the point() and set() methods are extremely slow in some circumstances when used with the default renderer. Using P2D or P3D will fix the problem. Grouping many calls to point() or set() together can also help. (<a href="http://dev.processing.org/bugs/show_bug.cgi?id=1094">Bug 1094</a>)
* =advanced
* <br><br>As of release 0149, this function ignores <b>imageMode()</b>.
throw new RuntimeException("Use filter(POSTERIZE, int levels) " +
"instead of filter(POSTERIZE)");
case OPAQUE:
for (int i = 0; i < pixels.length; i++) {
pixels[i] |= 0xff000000;
}
format = RGB;
break;
case THRESHOLD:
filter(THRESHOLD, 0.5f);
break;
// [toxi20050728] added new filters
case ERODE:
dilate(true);
break;
case DILATE:
dilate(false);
break;
}
updatePixels(); // mark as modified
}
/**
* Filters an image as defined by one of the following modes:<br><br>THRESHOLD - converts the image to black and white pixels depending if they are above or below the threshold defined by the level parameter. The level must be between 0.0 (black) and 1.0(white). If no level is specified, 0.5 is used.<br><br>GRAY - converts any colors in the image to grayscale equivalents<br><br>INVERT - sets each pixel to its inverse value<br><br>POSTERIZE - limits each channel of the image to the number of colors specified as the level parameter<br><br>BLUR - executes a Guassian blur with the level parameter specifying the extent of the blurring. If no level parameter is used, the blur is equivalent to Guassian blur of radius 1.<br><br>OPAQUE - sets the alpha channel to entirely opaque.<br><br>ERODE - reduces the light areas with the amount defined by the level parameter.<br><br>DILATE - increases the light areas with the amount defined by the level parameter
* =advanced
* Method to apply a variety of basic filters to this image.
* <P>
* <UL>
* <LI>filter(BLUR) provides a basic blur.
* <LI>filter(GRAY) converts the image to grayscale based on luminance.
* <LI>filter(INVERT) will invert the color components in the image.
* <LI>filter(OPAQUE) set all the high bits in the image to opaque
* <LI>filter(THRESHOLD) converts the image to black and white.
* Copies a region of pixels from one image into another. If the source and destination regions aren't the same size, it will automatically resize source pixels to fit the specified target region. No alpha information is used in the process, however if the source image has an alpha channel set, it will be copied as well.
* <br><br>As of release 0149, this function ignores <b>imageMode()</b>.
*
* @webref
* @brief Copies the entire image
* @param sx X coordinate of the source's upper left corner
* @param sy Y coordinate of the source's upper left corner
* @param sw source image width
* @param sh source image height
* @param dx X coordinate of the destination's upper left corner
* @param dy Y coordinate of the destination's upper left corner
* @param dw destination image width
* @param dh destination image height
* @param src an image variable referring to the source image.
* Blends a region of pixels into the image specified by the <b>img</b> parameter. These copies utilize full alpha channel support and a choice of the following modes to blend the colors of source pixels (A) with the ones of pixels in the destination image (B):<br><br>
* BLEND - linear interpolation of colours: C = A*factor + B<br><br>
* ADD - additive blending with white clip: C = min(A*factor + B, 255)<br><br>
* SUBTRACT - subtractive blending with black clip: C = max(B - A*factor, 0)<br><br>
* DARKEST - only the darkest colour succeeds: C = min(A*factor, B)<br><br>
* LIGHTEST - only the lightest colour succeeds: C = max(A*factor, B)<br><br>
* DIFFERENCE - subtract colors from underlying image.<br><br>
* EXCLUSION - similar to DIFFERENCE, but less extreme.<br><br>
* MULTIPLY - Multiply the colors, result will always be darker.<br><br>
* SCREEN - Opposite multiply, uses inverse values of the colors.<br><br>
* OVERLAY - A mix of MULTIPLY and SCREEN. Multiplies dark values, and screens light values.<br><br>
* HARD_LIGHT - SCREEN when greater than 50% gray, MULTIPLY when lower.<br><br>
* SOFT_LIGHT - Mix of DARKEST and LIGHTEST. Works like OVERLAY, but not as harsh.<br><br>
* DODGE - Lightens light tones and increases contrast, ignores darks. Called "Color Dodge" in Illustrator and Photoshop.<br><br>
* BURN - Darker areas are applied, increasing contrast, ignores lights. Called "Color Burn" in Illustrator and Photoshop.<br><br>
* All modes use the alpha information (highest byte) of source image pixels as the blending factor. If the source and destination regions are different sizes, the image will be automatically resized to match the destination size. If the <b>srcImg</b> parameter is not used, the display window is used as the source image.<br><br>
* As of release 0149, this function ignores <b>imageMode()</b>.
*
* @webref
* @brief Copies a pixel or rectangle of pixels using different blending modes
* @param src an image variable referring to the source image
* @param sx X coordinate of the source's upper left corner
* @param sy Y coordinate of the source's upper left corner
* @param sw source image width
* @param sh source image height
* @param dx X coordinate of the destinations's upper left corner
* @param dy Y coordinate of the destinations's upper left corner