文档

Java™ 教程
隐藏目录
绘制图像
路径:2D图形
教程:使用图像

绘制图像

正如你已经学到的那样,Graphics.drawImage方法会在指定位置绘制一张图片:

boolean Graphics.drawImage(Image img,
                   int x, int y,
                   ImageObserver observer);

x,y位置指定了图片左上角的位置。观察者observer参数用于通知应用程序异步加载的图片的更新。观察者observer参数通常不直接使用,并且对于BufferedImage类不需要,因此通常为null。

上述方法只处理整个图片被绘制的情况,将图片像素映射到用户空间坐标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将根据需要进行缩放。

下面的代码示例将一张图片分成四个象限,并随机将源图片的每个象限绘制到目标的不同象限。


注意:  如果你没有看到applet运行,请安装至少Java SE Development Kit (JDK) 7版本。下载链接

这个applet的完整代码在JumbledImageApplet.java中。

这个例子使用以下代码绘制了混乱的duke_skateboard.jpg图像。它迭代源图像的四个子图像,依次将每个子图像绘制到随机选择的目标象限中。

/* 将图像'bi'分成四个矩形区域,并将每个区域绘制到图像的不同部分,从而使图像混乱起来。
  * 'cells'是一个已经填充了将一个子区域绘制到另一个子区域的值的数组。
  */
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);
    }
}

过滤图像

除了复制和缩放图像外,Java 2D API还可以对图像进行过滤。 过滤是通过对源图像的像素应用算法来绘制或生成新图像。可以使用以下方法来应用图像过滤器:

void Graphics2D.drawImage(BufferedImage img,
                          BufferedImageOp op,
                          int x, int y)

BufferedImageOp参数实现了过滤器。下面的小程序表示在文本上方绘制了一个图像。拖动滑块可以通过图像显示更多或更少的文本,并使图像更或更少透明。


注意:  如果您看不到小程序运行,请安装至少Java SE Development Kit (JDK) 7版本。下载链接

以下代码显示了如何通过使用具有alpha通道的BufferedImage对象并使用RescaleOp对象来重新调整该alpha通道来完成过滤操作。alpha通道确定每个像素的半透明度,并指定了此图像覆盖的程度。

/* 创建一个带有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);

/*
 * 创建一个使图像50%不透明的重新调整滤镜操作。
 */
float[] scales = { 1f, 1f, 1f, 0.5f };
float[] offsets = new float[4];
RescaleOp rop = new RescaleOp(scales, offsets, null);

/* 绘制图像,应用滤镜 */
g2d.drawImage(bi, rop, 0, 0);

完整的示例在 SeeThroughImageApplet.java 中,包括使用滑块调整透明度从初始的50%开始的代码。该示例还需要 duke_skateboard.jpg 图像。

RescaleOp 对象只是可以创建的许多滤镜之一。Java 2D API 中内置了几个滤镜,包括以下几种:

下面的示例使用了上述每个滤镜以及缩放:


注意:  如果您看不到 applet 运行,请安装至少 Java SE Development Kit (JDK) 7 版本。

此 applet 的完整代码在 ImageDrawingApplet.java 中,该 applet 需要 bld.jpg 图像。

使用下拉菜单选择图像缩放或滤镜操作。


上一页: 阅读/加载图像
下一页: 创建并绘制图像