`
JAVA海洋
  • 浏览: 618214 次
  • 性别: Icon_minigender_1
  • 来自: 太原
社区版块
存档分类
最新评论

在Java应用程序中创建图像

阅读更多
  合成图像

  您不必从文件中读取所有的图像 — 您可以创建自己的图像。要创建自己的图像,最灵活的方法是用一个 BufferedImage 对象,它是 Image 类的一个子类,它把图像数据存储在一个可以被访问的缓冲区中。它还支持各种存储像素数据的方法:使用或不使用 alpha 通道、不同种类的颜色模型以及颜色组件的各种精确度。ColorModel 类提供一种灵活的方法定义各种颜色模型,以和 BufferedImage 对象一起使用。为了理解颜色模型工作的基本知识,我们将只使用一个缺省的颜色模型,其颜色组件由 RGB 值和一个缓冲类型(存储 8 位的 RGB 颜色值加上一个 alpha 通道)组成。这一缓冲类型由 BufferedImage 类中的常量 TYPE_INT_ARGB 指定,它意味着每个像素要用一个 int 值。每个像素的值是以 8 位字节形式存储一个 alpha 组件加上 RGB 颜色组件。我们可以用给定的宽度和高度创建一个这种类型的 BufferedImage 对象,代码语句如下:

int width = 200;
int height = 300;
BufferedImage image = new BufferedImage(width,
height,BufferedImage.TYPE_INT_ARGB);

  这段代码创建了一个 BufferedImage 对象,它代表一个 200 像素宽、300 像素高的图像。为了应用这个图像,我们需要有图形上下文,而 BufferedImage 对象的 createGraphics() 方法就返回一个与该图像相关的 Graphics2D 对象:

int width = 200;
Graphics2D g2D = image.createGraphics();

  使用 g2D 对象的操作会修改 BufferedImage 对象 image 的像素。利用这个对象,您现在完全有能力应用 BufferedImage 对象。您可以绘制形状、图像、GeneralPath 对象或任何别的东西,还可以为图形上下文设置 alpha 组合对象。您同时还拥有 Graphics2D 对象提供的全部仿射变形能力。

  如果要从 BufferedImage 对象获取单个像素,可以通过调用它的 getRGB() 方法,并提供该像素的 x,y 坐标作为 int 类型的参数。这个像素会按 TYPE_INT_ARGB 格式以 int 类型返回,它由四个 8 位的值(代表 alpha 值和 RGB 颜色组件)组成一个 32 位字。同时 getRGB() 还有一个重载的版本,它从一部分图像数据中返回一个像素数组。您也可以通过调用 setRGB() 方法来设置单个像素。前两个参数是该像素的坐标值,第三个参数是待设定的值,类型为 int。这个方法也有一个版本可以设置像素数组的值。

  至此我们已经完成了像素操作的学习。下面我们要建立一个 applet,它在 Wrox 徽标背景上使 BufferedImage 对象具有动画效果。我们的示例还将演示怎样能让图像局部透明。applet 的基本内容如下所示:

import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;
import javax.swing.*;

public class ImageDrawDemo extends JApplet
{
 // The init() method to initialize everything...
 // The start() method to start the animation...
 // The stop() method to stop the animation...
 // The ImagePanel class defining the panel displaying the animation...
 // Data members for the applet...
}

  创建一个图像

  一个子图形是一个小的图形图像,可以将其绘制在静态图像以创建动画。要创建动画效果,您只要随着时间推移,在不同的位置和方向上绘制子图形。当然,利用坐标系的变形可以使之简化许多。游戏经常使用子图形 — 由于您只需要在一个静态背景上绘制子图形,所以可以使动画所占用的处理器的时间大大减少。我们对使用 BufferedImage 对象的兴趣意味着我们将不再花费精力去研究减少处理器时间的最佳技术,而是把注意力放在理解怎样才能在一个程序内部创建和使用图像上。

  我们的 BufferedImage 对象看上去如图 1 中的图像:


图 1. BufferedImage 子图形

  这个图像是一个以 spriteSize 为边长的正方形。图像其它部分的尺寸值都与这个边长相关。实际上这里只有两个几何实体,一条线和一个圆,都在不同位置和方向重复出现。如果我们创建一个 Line2D.Double 对象代表线,创建一个 Ellipse2D.Double 对象代表圆,那么我们就可以通过移动用户坐标系和画这两个对象中的一个或其它的对象而画出整个图像。

  如果是按真正面向对象的方法,应该定义一个类代表一个子图形,可能是作为 BufferedImage 的一个子类,但由于我们是在探索使用 BufferedImage 对象的技巧,因此用一个 createSprite() 方法来画出 BufferedImage 对象上的子图形会更适合我们的目的。因为该方法只是我们的 applet 类的一个成员,所以我们将为 applet 添加数据成员以存储任何需要的数据。您可以把我们将使用的数据成员插入到 applet 类中,如下所示:

double totalAngle; // Current angular position of sprite
double spriteAngle; // Rotation angle of sprite about its center
ImagePanel imagePanel; // Panel to display animation

BufferedImage sprite; // Stores reference to the sprite
int spriteSize = 100; // Diameter of the sprite
Ellipse2D.Double circle; // A circle - part of the sprite
Line2D.Double line; // A line - part of the sprite

// Colors used in sprite
Color[] colors = {Color.red , Color.yellow, Color.green , Color.blue,
Color.cyan, Color.pink , Color.magenta, Color.orange};

java.util.Timer timer; // Timer for the animation
long interval = 50; // Time interval msec between repaints

  这些成员的一般用途可以从注释中清楚地看到。下面我们要看一看开发代码时它们是怎样被使用的。

  createSprite() 方法需要做的第一件事就是创建 BufferedImage 对象 sprite,然后我们还需要一个 Graphics2D 对象用于在 sprite 图像上绘画。下面就是完成这些操作的代码:

BufferedImage createSprite(int spriteSize)
{
 // Create image with RGB and alpha channel
 BufferedImage sprite = new BufferedImage(spriteSize, spriteSize,
 BufferedImage.TYPE_INT_ARGB);

 Graphics2D g2D = sprite.createGraphics(); // Context for buffered image
 // plus the rest of the method...
}

  sprite 对象的宽和高的值都是 spriteSize,图像的类型为 TYPE_INT_ARGB,就是说每个像素的 alpha 值和颜色组件是以一个单独的 int 值存储的,而颜色是以 8 位的红、绿、蓝组件的形式存储的。这意味着我们的 sprite 图像将占用 40,000 字节,这只是浏览一个网页会占用的内存的很小一部分。而这并不影响网页的下载时间,因为在执行 applet 的时候,这部分内存是在本地机器上被分配的。除了作为网页本身的 HTML 文件的内容外,下载时间还取决于 applet 的 .class 文件的大小,以及在它执行时下载的图像或其它文件。

  创建一个透明的背景

  在 sprite 图像中,alpha 通道是很重要的,因为我们希望背景能完全透明。在绘画过程中,只有 sprite 对象本身应该是可见的,而不是整个 100×100 的矩形图像。我们可以很容易地实现这一目的,只要开始先使整个 sprite 图像区域透明(即,alpha 值为 0.0f),然后把我们想要画的图形绘制在上面,使之不透明(alpha 值为 1.0f)。以下是使整个图像透明的代码:

// Clear image with transparent alpha by drawing a rectangle
g2D.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
Rectangle2D.Double rect = new Rectangle2D.Double(0,0,spriteSize,spriteSize);
g2D.fill(rect);

  我们首先使用 AlphaComposite 对象按照 CLEAR 规则设置 alpha 合成值,把颜色组件设置为零,又通过设置 alpha 值为 0.0f,使之透明。然后我们填充一个覆盖整个图像区域的矩形。我们不必设置颜色值,因为根据 CLEAR 规则,每个像素的前景和背景色所占成分都是零,所以这两者都不参与像素的生成。但我们仍要填充该矩形,因为这将确定被操作的图像像素。

  这里,我们可以稍微了解一下怎样控制图像的质量。

  着色微调

  对着色操作的许多方面而言,都有一个在质量和速度间选择的问题。着色操作就像大多数事情一样 — 质量是需要代价的,而这里的代价就是处理时间。所有的着色操作都有缺省设置,其中存在一个选择,缺省设置是特定于平台的,但您可以通过调用用于着色的 Graphics2D 对象的 setRenderingHint() 方法自己选择。虽然只有一些微调,如果您的计算机不支持与您指定的微调相对应的着色操作选项,这些微调就无法生效。

  通过添加以下对 createSprite() 方法的调用,可以确保得到由我们的 alpha 合成操作可能生成的最好效果。

BufferedImage createSprite(int spriteSize)
{
 // Create image with RGB and alpha channel
 BufferedImage sprite = new BufferedImage(spriteSize, spriteSize, BufferedImage.TYPE_INT_ARGB);

 Graphics2D g2D = sprite.createGraphics(); // Context for buffered image

 // Set best alpha interpolation quality
 g2D.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);

 // Clear image with transparent alpha by drawing a rectangle
 g2D.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
 Rectangle2D.Double rect = new Rectangle2D.Double(0,0,spriteSize,spriteSize);
 g2D.fill(rect);

 // plus the rest of the method...
}

  RenderingHints 类定义了多种着色微调,它们存储在一个映射集的 Graphics2D 对象里。 setRenderingHint() 方法的参数是一个键以及对应的键值。在我们的代码中,第一个参数是代表 alpha 合成微调的键,第二个参数是该微调的值。该微调的其它可能的值有 VALUE_ALPHA_INTERPOLATION_DEFAULT,代表平台缺省值;以及 VALUE_ALPHA_INTERPOLATION_SPEED,代表追求速度而不是质量。

  您还可以为下面的键提供微调:

描述
KEY_ANTIALIASING 决定是否使用抗锯齿。当着色有倾斜角度的线时,通常会得到一组阶梯式的像素排列,使这条线看上去不平滑,经常被称为 锯齿状图形。抗锯齿是一种技术,它设置有倾斜角度的线的像素亮度,以使线看起来更平滑。因此,这个微调是用来决定在着色有倾斜角度的线时是否在减少锯齿状图形上花费时间。可能的值有 VALUE_ANTIALIAS_ON, _OFF 或 _DEFAULT。
KEY_COLOR_RENDERING 控制颜色着色的方式。可能的值有 VALUE_COLOR_RENDER_SPEED, _QUALITY 或 _DEFAULT。
KEY_DITHERING 控制如何处理抖动。抖动是用一组有限的颜色合成出一个更大范围的颜色的过程,方法是给相邻像素着色以产生不在该组颜色中的新的颜色幻觉。可能的值有 VALUE_DITHER_ENABLE, _DISABLE 或 _DEFAULT。
KEY_FRACTIONALMETRICS 文本的质量。可能的值有 VALUE_FRACTIONALMETRICS_ON, _OFF 或 _DEFAULT。
KEY_INTERPOLATION 确定怎样做内插。

  在对一个源图像做变形时,变形后的像素很少能够恰好对应目标像素位置。在这种情况下,每个变形后的像素的颜色值不得不由周围的像素决定。

  内插就是实现上述过程。有许多可用的技术。可能的值,按处理时间从最多到最少,是 VALUE_INTERPOLATION_BICUBIC, _BILINEAR 或 _NEAREST_NEIGHBOR。

  KEY_RENDERING 确定着色技术,在速度和质量之间进行权衡。可能的值有 VALUE_RENDERING_SPEED, _QUALITY 或 _DEFAULT。

  KEY_TEXT_ANTIALIASING 确定对文本着色时是否抗锯齿。可能的值有 VALUE_TEXT_ANTIALIASING_ON, _OFF 或 _DEFAULT。

  我们绕得已经够远了。让我们回到绘制 sprite 上……
分享到:
评论

相关推荐

    在 Java 应用程序中创建图像.rar_图形 Java

    在Java应用程序中创建图像是一项重要的任务,特别是在开发用户界面或者进行数据可视化时。Java提供了丰富的图形库和API,使得开发者可以轻松地实现图形绘制和着色。本篇将深入探讨如何在Java中创建图像,以及如何在...

    Java应用程序中创建图像

    在Java应用程序中创建图像,主要涉及的是`BufferedImage`对象的使用,它是`Image`类的一个子类,允许我们直接操作图像数据。`BufferedImage`提供了多种存储像素数据的方法,包括是否包含alpha通道、不同颜色模型以及...

    Java图像处理类库 Java Image Filters

    在开发过程中,`Manifest`文件通常包含了关于Java应用程序的元数据,如主类名和依赖库。`build.xml`是Ant构建工具的配置文件,用于自动化构建过程,包括编译源代码、打包和部署等。`dist`目录则存放构建后的可执行...

    JAVA基本数字图像处理

    在Java中,可以创建一个滤波器模板,然后对每个像素及其邻域应用模板进行运算,得到平滑后的像素值。 以上这些基本操作构成了Java数字图像处理的基础。通过理解这些概念和技巧,开发者可以进一步探索更复杂的图像...

    java小应用程序 连续显示图片

    7. **嵌入网页**:将Java小应用程序嵌入网页通常通过Java Web Start技术实现,这是一个基于Java的客户端应用启动技术,允许用户通过浏览器下载并运行Java应用程序。 以下是实现上述功能的简单步骤: 1. 创建JFrame...

    JAVA 在图像处理中的应用

    解析这些通道并将其合并到最终图像中是重要的步骤。 5. **元数据**:PSD文件可能包含关于图像的各种元数据,如作者、版权信息、创建日期等。这些信息需要被提取并可能在程序中显示或记录。 6. **图像输出**:最后...

    Java应用程序设计接口

    通过深入学习Java应用程序设计接口中的窗口部分,开发者能够熟练掌握创建和管理GUI的技巧,从而开发出具有吸引力且用户体验良好的Java应用程序。书中可能还会涵盖更多的高级主题,如拖放操作、打印支持、Swing组件的...

    java 画图程序 图像变形 注释详细

    在Java编程语言中,开发一个类似Windows画图的小程序是一项有趣的挑战,它涉及到图形用户界面(GUI)的设计和图像处理技术。本项目的核心是利用Java的AWT(Abstract Window Toolkit)或Swing库来创建图形界面,并...

    java imageProcess 图像处理程序模板

    Java图像处理程序模板是用于开发图像操作和分析应用的基础框架,它可以帮助开发者快速构建功能丰富的图像处理项目。这个模板可能包含了一系列预定义的类和方法,涵盖了常见的图像处理任务,如图像读取、显示、保存、...

    简单Java图像显示程序

    本项目名为“简单Java图像显示程序”,显然它的主要目的是展示如何在Java环境中加载和显示图像。以下是对这个程序可能涉及的知识点的详细解释: 1. **Java AWT 和 Swing 库**: - AWT(Abstract Window Toolkit)...

    使用Java开发的OCR程序 根据图像识别转换成中文

    在IT行业中,OCR(Optical Character Recognition,光学字符识别)技术是一种广泛应用的技术,它能够将图像中的文字识别并转换为可编辑的文本格式。在这个Java开发的OCR程序中,我们聚焦于如何使用Java来实现这一...

    用Java写成的改变图像透明度合成图像程序

    通过调整图像的alpha值,我们可以实现图像从背景中淡入或淡出的效果,这在许多应用中都非常有用,如创建叠加层、动画或设计元素。 在Java中,AWT和Swing库提供了对图像处理的支持。`java.awt.image.BufferedImage`...

    java编写的图像处理程序,java做图像处理,Java

    `图像处理学案例分析展示软件.jar`是一个可执行的Java应用程序,它封装了所有图像处理的逻辑和资源,用户可以直接运行,无需编译源代码。运行这个`.jar`文件,用户可以看到图像处理的界面和功能。 `使用说明书_.pdf...

    数字图像处理 java 语言描述

    由于图像处理通常涉及大量的计算,因此在Java中进行图像处理时,应考虑使用多线程、缓存策略以及避免不必要的对象创建,以提高程序运行效率。 总结来说,Java语言为数字图像处理提供了一个强大而灵活的平台,无论你...

    JAVA-web数字图像处理基础

    11. **图形用户界面(GUI)设计**:在Java Web应用中展示图像,可能需要创建自定义的GUI组件,如图片查看器或编辑器。Swing和JavaFX提供了构建此类界面的工具。 12. **框架和库**:如JavaFX、JavaCV、OpenCV、Image...

    JAVA 实现的获取图像像素程序

    在JAVA编程语言中,获取图像像素是一项常见的任务,特别是在图像处理、计算机视觉或者数据分析等领域。以下将详细讲解如何使用JAVA实现获取图像像素的程序,并探讨相关的知识点。 首先,我们需要了解JAVA中的`java....

    简单的java applet图像移动重画实例

    Java Applet是Java技术在早期Web开发中的一种应用方式,它允许开发者创建可以在浏览器中运行的小型应用程序。在这个“简单的java applet图像移动重画实例”中,我们将深入探讨Java Applet的基础知识,以及如何实现...

    基于javacv实现图像拼接的源代码

    特征匹配是识别不同图像中的相同对象或特征,图像变换则是调整图像的几何形状,以便它们在拼接时能正确对齐,而图像融合则涉及将多个图像的像素值进行合成,以创建无缝的全景图像。 在NetBeans这样的集成开发环境中...

    java图形与图像处理

    Java图形与图像处理是Java程序设计的一个重要领域,主要涉及如何在Java环境中创建和操作图形以及处理图像。在Java中,我们通常使用`java.awt`和`java.awt.image`这两个包来实现图形与图像的处理。 标题中的"java...

    Java实现图像的模糊与锐化Java实用源码整理learns

    在Java编程语言中,图像处理是一项重要的...通过深入理解这些概念和技术,你可以在Java应用程序中实现强大的图像处理功能。记得实践是检验真理的唯一标准,尝试编写代码并观察结果,这将有助于你更好地掌握这些知识点。

Global site tag (gtag.js) - Google Analytics