控制动态servlet图形处理(2)(2)

2008-02-23 09:40:59来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折





图 3. 重要的 javax.servlet.jsp.tagext 类



清单 2 显示了 ImageSizerTag 类的 doEndTag 方法。这几乎是实现定制 JSP 标记所需的全部 Java 代码。它是一大段代码,但是它将有助于您的理解,以便全面地了解该方法。首先,任何 HTTP 请求参数都保存在 HTTP 会话中。该请求带有一个属性,如对于图像大小的用户首选项,并将其保存在会话中,以便它可以跟随用户从一个页面到另一个页面。要扩充该标记的功能,可以扩展它,使之可将用户首选项保存在 cookie 中,这样用户下一次访问站点时就可使用其首选项。

下一步是装入缺省图像,JSP 页面使用它来作为基图,所有其它图像都根据基图来调整大小。这里,java.awt.Toolkit 请求图像,图像是用 ImageSizer.waitForImage 装入的,并对其进行了检查,以了解其是否进行了正确的缩放。需要进行装入暂停,因为 Java 图像是异步装入的,当请求它们时并非始终完全可用。在本示例中,ImageSizer 辅助类执行整个图像处理操作,下一节将对此做进一步介绍。如果宽和高匹配,则无须重新调整图像大小,并将跳过 if 这一大块代码,而且使用图像名称和当前大小编写 HTML 图像标记。这就是 JSP 实现模拟 HTML 图像标记所需做的全部工作。

如果用户请求新的图像大小,那么 ImageSizer 辅助类会重新调整图像的大小。使用文件大小给图像文件指定新的名称,文件是 JPEG 编码的,并写到文件系统。接着,将在 HTML 图像标记输出中使用刚刚重新调整大小的文件。该标记的备用实现可能会将文件保存为 GIF 或 PNG 格式,或者甚至会通过内存来提供图像以节省磁盘空间。但是,清单 2 将重新调整大小的文件高速缓存到了磁盘,以备将来使用。因此,第一次重新调整大小时需要花费一些服务器处理时间,但是随后对图像大小进行请求时根本不需要处理。该示例的扩展可能会检查可用的磁盘空间,以便于帮助平衡有限的文件空间与您希望提供给客户机的即时信息之间的折衷。

调整图像大小



前一节研究了编写定制 JSP 标记的步骤。ImageSizerTag 类会自动重新调整图像的大小以匹配用户的首选项。这一节提供了有关您可以如何使用 ImageSizer 类来重新调整图像大小并将其保存为 JPEG 文件的更多详细信息。利用 java.awt.Image 类中的 getScaledInstance 方法,很容易在 Java 代码中重新调整图像的大小。利用新的宽和高调用这个方法,或者为某个参数提供一个值 -1 以保持纵横比,您可以得到新的重新调整过大小的图像。但是,就象任何 Java 图像一样,该图像并不是立即可用的,因此您必须使用 java.awt.MediaTracker 以等待图像完全装入。ImageSizer 的 waitForImage 方法封装了该代码。

在该示例中,最难的设计点在于决定如何保存图像。用 Java 编程编码和保存图像有很多选择,所有选择都有不同的权衡。

com.sun.image.codec。该包在 Java 2 SDK 1.2 和 1.3 实现中是可用的,但它在私有(private)包中,在将来的 Java 2 版本中这可能会发生变化。该包只限于 JPEG 编码。

Java Image I/O API。在 Java 2 SDK 1.4 中,该包是公共的和标准的。但是,在撰写本文时,还没有使用 SDK 1.4 的 J2EE 版本。该包提供了良好的图像操作功能和编码选项。

Java 高级映象 API(Java Advanced Imaging API)。这个 API 是一个标准扩展,但是使用它需要安装包 — 您的 Web 管理员可能不支持该工作。

ACME GIF 编码器(ACME GIF Encoder)。该软件及许多其它第三方图像包很有用,您可以将它们合并在示例代码中,但是有个费用和可维护性的问题。同其它选择不同,该软件不是免费的,并且不完全支持 GIF 标准。

对于清单 3,我们使用 com.sun.image.codec 包,因为它在所有 J2EE 1.2 和 1.3 Web 服务器容器(如 IBM WebSphere 和 Apache Tomcat)中都可用。编码器很简单,并且是 100% 纯 Java 代码,但是它们是 com.sun 包中的。但是,从长远考虑,Java Image I/O 包可能是发展的方向。在图像转换特性以及保存为多种文件格式的能力方面,它比较强大。直到 Java 2 V1.4 时 Java Image I/O 包才会成为标准。

既然已经决定了使用哪个图像处理包,那么保存 JPEG 文件的代码就相当简单了。ImageSizer 的 encodeJPEG 方法封装了这个过程:

java.awt.image.BufferedImage 对象,这是一个增强的 Java Image 子代,是从重新调整过大小的输出图像创建的。注释在代码中标明了一个位置,可以在这里扩展示例以将徽标、水印、时间戳记或版权信息添加到图像。

在将 Image 转换为 BufferedImage 之后,在输出流上创建一个 JPEGImageEncoder 对象。输出编码质量的范围从 0.0(最差)到 1.0(最佳)。缺省值是 0.75,但 0.95 将生成较大的文件大小,它带有更详细的图像。作为该示例的扩展,您可以考虑由图像大小来决定质量 — 较小的图像需要较高的质量设置,而较大的图像需要较低的设置。

将图像编码到输出流,并对该流进行刷新以确保所有信息都显示在图像文件中。

清单 3. ImageSizer encodeJPEG 实现

// Encodes the given image at the given

// quality to the output stream.

public static void encodeJPEG

  ( OutputStream outputStream,

  Image outputImage, float outputQuality )

  throws java.io.IOException {



  // Get a buffered image from the image.

  BufferedImage bi = new BufferedImage

    ( outputWidth, outputHeight,

      BufferedImage.TYPE_INT_RGB );

  Graphics2D biContext =

    bi.createGraphics( );

  biContext.drawImage

    ( outputImage, 0, 0, null );

  // Additional drawing code, such as

  // watermarks or logos can be placed here.



  // com.sun.image.codec.jpeg package

  // is included in Sun and IBM sdk 1.3.

  JPEGImageEncoder encoder =

    JPEGCodec.createJPEGEncoder

    ( outputStream );

  // The default quality is 0.75.

  JPEGEncodeParam jep =

    JPEGCodec.getDefaultJPEGEncodeParam

    ( bi );

  jep.setQuality( outputQuality, true );

  encoder.encode( bi, jep );

  outputStream.flush();

} // encodeImage
			   
			   

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:JSTL改进JSP来简化网页的实现过程(1)

下一篇:JSTL改进JSP来简化网页的实现过程(2)