绘制图像
如您所知,Graphics.drawImage
方法在特定位置绘制图像:
boolean Graphics.drawImage(Image img,
int x, int y,
ImageObserver observer);
x,y
位置指定图像左上角的位置。 observer
参数通知应用程序对异步加载的映像的更新。 observer
参数不经常直接使用,并且BufferedImage类不需要它,因此它通常为 null。
所描述的方法仅解决了要绘制整个图像的情况,将图像像素 Map 到用户空间坐标 1:1.有时,应用程序需要绘制图像的一部分(子图像),或者缩放图像以覆盖绘图表面的特定区域,或者在绘制之前对图像进行转换或过滤。
drawImage()
方法的重载执行这些操作。例如,以下drawImage()
方法的重载使您能够绘制当前可用图像中指定图像的指定区域的尽可能多的区域,并将其缩放以适合目标可绘制表面的指定区域内:
boolean Graphics.drawImage(Image img,
int dstx1, int dsty1, int dstx2, int dsty2,
int srcx1, int srcy1, int srcx2, int srcy2,
ImageObserver observer);
src
参数代表要复制和绘制的图像区域。 dst
参数显示源区域要覆盖的目标区域。 dstx1, dsty1
坐标定义绘制图像的位置。通过以下表达式计算目标区域上的宽度和高度尺寸:(dstx2-dstx1), (dsty2-dsty1)
。如果源区域和目标区域的尺寸不同,则 Java 2D API 将根据需要放大或缩小。
以下代码示例将图像划分为四个象限,并将源图像的每个象限随机绘制到目标的不同象限中。
Note:
如果看不到 Servlets 正在运行,则需要至少安装Java SE 开发套件(JDK)7版本。
此 Servlets 的完整代码在JumbledImageApplet.java中。
本示例使用以下代码绘制混杂的duke_skateboard.jpg
图像。迭代源的四个子图像,依次将每个子图像绘制到随机选择的目标象限中。
/* divide the image 'bi' into four rectangular
* areas and draw each of these areas in to a
* different part of the image, so as to jumble
* up the image. 'cells' is an array which has
* been populated with values which redirect
* drawing of one subarea to another subarea.
*/
int cellWidth = bi.getWidth(null)/2;
int cellHeight = bi.getHeight(null)/2;
for (int x=0; x<2; x++) {
int sx = x*cellWidth;
for (int y=0; y<2; y++) {
int sy = y*cellHeight;
int cell = cells[x*2+y];
int dx = (cell / 2) * cellWidth;
int dy = (cell % 2) * cellHeight;
g.drawImage(bi,
dx, dy,
x+cellWidth, dy+cellHeight,
sx, sy,
sx+cellWidth, sy+cellHeight,
null);
}
}
Filtering Images
除了复制和缩放图像外,Java 2D API 还可以过滤图像。 过滤是通过对源图像的像素应用算法来绘制或生成新图像。可以使用以下方法来应用图像滤镜:
void Graphics2D.drawImage(BufferedImage img,
BufferedImageOp op,
int x, int y)
BufferedImageOp
参数实现过滤器。以下 Servlets 表示在文本顶部绘制的图像。拖动滑块以在图像中显示或多或少的文本,并使图像或多或少透明。
Note:
如果看不到 Servlets 正在运行,则需要至少安装Java SE 开发套件(JDK)7版本。
以下代码显示了如何通过对具有* alpha *通道的BufferedImage
对象进行操作并使用RescaleOp
对象重新缩放该 alpha 通道来完成过滤操作。 Alpha 通道确定每个像素的半透明性。它还指定此图像覆盖的程度。
/* Create an ARGB BufferedImage */
BufferedImage img = ImageIO.read(imageSrc);
int w = img.getWidth(null);
int h = img.getHeight(null);
BufferedImage bi = new
BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.getGraphics();
g.drawImage(img, 0, 0, null);
/*
* Create a rescale filter op that makes the image
* 50% opaque.
*/
float[] scales = { 1f, 1f, 1f, 0.5f };
float[] offsets = new float[4];
RescaleOp rop = new RescaleOp(scales, offsets, null);
/* Draw the image, applying the filter */
g2d.drawImage(bi, rop, 0, 0);
SeeThroughImageApplet.java代表的完整示例包括使用滑块从初始 50%调整透明度的代码。此示例还需要duke_skateboard.jpg图片。
RescaleOp
对象只是可以创建的许多过滤器之一。 Java 2D API 具有多个内置过滤器,包括以下内容:
-
ConvolveOp
。根据源图像中的周围像素计算每个输出像素。它可以用于模糊或锐化图像。 -
AffineTransformOp
。通过对像素位置进行变换,此滤镜将源中的像素 Map 到目标中的其他位置。 -
LookupOp
。该过滤器使用应用程序提供的查找表来重新 Map 像素颜色。 -
RescaleOp
。此滤镜将颜色乘以某个系数。可用于使图像变亮或变暗,增加或减少其不透明度等。
以下示例使用上述每个过滤器以及缩放比例:
Note:
如果看不到 Servlets 正在运行,则需要至少安装Java SE 开发套件(JDK)7版本。
此 Servlets 的完整代码在ImageDrawingApplet.java中,并且此 Servlets 需要bld.jpg图像。
使用下拉菜单选择图像缩放或过滤操作。