There is no way to render a subset of the entire image without using either a cropping filter or the clipping mechanism of the Graphics object. This situation is further compounded by the fact that the clip attribute of the Graphics object can only be set to a more restrictive value, it can never be expanded or restored to a previous clip area.
The existing methods to scale an image also do not allow the programmer to flip an image horizontally or vertically by scaling it to a negative size or by any other means. Even though other arbitrary manipulations of images are not supported, the lack of flipping is notable mainly because it is easily managed with minor mathematical modifications to the already supported scaling algorithms.
drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer)
An interesting note about these new methods is that, while the former drawImage() methods may create a totally new representation of the image for the screen by rereading the raw image data in an asynchronous thread, the new methods will always use the pixels from the unscaled version of the image to draw to the screen. As a result, the 2 new methods will complete synchronously as long as the full size version of the image has previously been loaded and converted as indicated by a MediaTracker or other image status API.
Another interesting change in the coordinate specifications of the new methods is the use of two coordinates to define the source and destination rectangles. Since negative widths and heights carry existing meanings in the rest of the Java APIs, the new methods use the new coordinate pair specification to allow explicit control over which dimensions get flipped. This new system is also more convenient for some applications which may be tracking the corner of the image by following a user dragging the mouse. There is no need to decompose drag start and end coordinates into an x,y,w,h format.
Following is sample code showing the use of the old API to perform image cropping:
import java.awt.*; import java.applet.*; public class ImgCropExample extends Applet { Image bgimg, img2; public void paint(Graphics g) { // Draw a background image g.drawImage(bgimg, 0, 0, this); // Draw the upper left 100x100 portion of another image at 10,10 Graphics g2 = g.create(); g2.clipRect(10, 10, 100, 100); g2.drawImage(img2, 10, 10, this); g2.dispose(); // reclaims resources more quickly // Now continue drawing with original clip area g.fillRect(0, 0, 10, 10); } }
Following is sample code showing the use of the new API to perform image cropping:
import java.awt.*; import java.applet.*; public class ImgCropExample extends Applet { Image bgimg, img2; public void paint(Graphics g) { // Draw a background image g.drawImage(bgimg, 0, 0, this); // Draw the upper left 100x100 portion of another image at 10,10 g.drawImage(img2, 10, 10, 110, 110, 0, 0, 100, 100, this); // Now continue drawing with original clip area g.fillRect(0, 0, 10, 10); } }
Following is sample code showing the use of the new API to perform image flipping:
import java.awt.*; import java.applet.*; public class ImgCropExample extends Applet { Image img2; public void paint(Graphics g) { // Draw the center 100x100 portion of a 200x200 image // at location 10, 10, flipped horizontally. g.drawImage(img2, 10, 10, 110, 110, 150, 50, 50, 150, this); } }