Working with Images in Java – 在Java中处理图像

最后修改: 2016年 12月 26日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we are going to take a look at a few available image-processing libraries, and perform simple image processing operation – loading an image and drawing a shape on it.

在本教程中,我们将了解一些可用的图像处理库,并进行简单的图像处理操作–加载图像并在上面画出一个形状。

We’ll try out AWT (and a bit of Swing) library, ImageJ, OpenIMAJ, and TwelveMonkeys.

我们将试用AWT(和一点Swing)库、ImageJ、OpenIMAJ和TwelveMonkeys。

2. AWT

2.AWT

AWT is a built-in Java library that allows a user to perform simple operations related to display, like creating a window, defining buttons and listeners and so on. It also includes methods that allow a user to edit images. It does not require installation since it is shipped with Java.

AWT是一个内置的Java库,允许用户执行与显示有关的简单操作,如创建一个窗口,定义按钮和监听器等。它还包括允许用户编辑图像的方法。它不需要安装,因为它是与Java一起提供的。

2.1. Loading an Image

2.1.加载一个图像

The first thing is to create a BufferedImage object from a picture saved on our disk drive:

第一件事是用保存在我们磁盘驱动器上的图片创建一个BufferedImage对象。

String imagePath = "path/to/your/image.jpg";
BufferedImage myPicture = ImageIO.read(new File(imagePath));

2.2. Editing an Image

2.2.编辑一个图像

To draw a shape on an image, we will have to use Graphics object related to loaded image. Graphics object encapsulates properties needed to perform basic rendering operations. Graphics2D is a class extending Graphics. It provides more control over two-dimensional shapes.

为了在图像上绘制一个形状,我们必须使用与加载的图像相关的Graphics对象。Graphics对象封装了执行基本渲染操作所需的属性。Graphics2D是一个扩展Graphics的类。它提供了对二维图形的更多控制。

In this particular case, we need Graphic2D to extend shape width to make it clearly visible. We achieve it by increasing its stroke property. Then we set a color, and draw a rectangle in such way that shape will be ten px from image borders:

在这种特殊情况下,我们需要Graphic2D扩展形状的宽度,使其清晰可见。我们通过增加它的stroke属性来实现它。然后,我们设置一个颜色,并画一个矩形,使形状距离图像的边界有10px。

Graphics2D g = (Graphics2D) myPicture.getGraphics();
g.setStroke(new BasicStroke(3));
g.setColor(Color.BLUE);
g.drawRect(10, 10, myPicture.getWidth() - 20, myPicture.getHeight() - 20);

2.3. Displaying an Image

2.3.显示一个图像

Now that we have drawn something on our image, we would like to display it. We can do it using Swing library objects. First, we create JLabel object which is representing a display area for text or/and image:

现在我们已经在我们的图像上画了一些东西,我们想显示它。我们可以使用Swing库的对象来实现。首先,我们创建JLabel对象,它代表一个文本或/和图像的显示区域。

JLabel picLabel = new JLabel(new ImageIcon(myPicture));

Then add our JLabel to JPanel, which we can treat as <div></div> of Java-based GUI:

然后把我们的JLabel添加到JPanel,我们可以把它当作基于Java的GUI的<div></div>/em>。

JPanel jPanel = new JPanel();
jPanel.add(picLabel);

In the end, we add everything to JFrame which is window displayed on a screen. We have to set size so that we don’t have to expand this window every time we run our program:

最后,我们将所有内容添加到JFrame中,它是显示在屏幕上的窗口。我们必须设置大小,这样我们就不必在每次运行我们的程序时扩大这个窗口。

JFrame f = new JFrame();
f.setSize(new Dimension(myPicture.getWidth(), myPicture.getHeight()));
f.add(jPanel);
f.setVisible(true);

3. ImageJ

3.ImageJ

ImageJ is a Java-based software created for working with images. It has quite a lot of plugins, available here. We will be using API only, as we want to perform processing by ourselves.

ImageJ是一个基于Java的软件,为处理图像而创建。它有相当多的插件,可在这里。我们将只使用API,因为我们想自己进行处理。

It is quite a powerful library, better than Swing and AWT, as it’s creation purpose was image processing and not GUI operations. Plugins contain many free to use algorithms, which is a good thing when we want to learn image processing and quickly see the results, rather than solve math and optimization problems laying under IP algorithms.

它是一个相当强大的库,比Swing和AWT更好,因为它的创建目的是图像处理而不是GUI操作。插件包含许多免费使用的算法,当我们想学习图像处理并快速看到结果时,这是件好事,而不是解决IP算法下的数学和优化问题。

3.1. Maven Dependency

3.1.Maven的依赖性

To start working with ImageJ, simply add a dependency to your project’s pom.xml file:

要开始使用ImageJ,只需在项目的pom.xml文件中添加一个依赖关系。

<dependency>
    <groupId>net.imagej</groupId>
    <artifactId>ij</artifactId>
    <version>1.51h</version>
</dependency>

You will find the newest version in the Maven repository.

您可以在Maven资源库中找到最新的版本。

3.2. Loading an Image

3.2.加载一个图像

To load the image, you need to use the openImage() static method, from IJ class:

要加载图像,你需要使用openImage() 静态方法,来自IJ类。

ImagePlus imp = IJ.openImage("path/to/your/image.jpg");

3.3. Editing an Image

3.3.编辑一个图像

To edit an image, we will have to use methods from ImageProcessor object attached to our ImagePlus object. Think of it as about Graphics object in AWT:

要编辑一张图片,我们必须使用ImageProcessor对象的方法,该对象附加到我们的ImagePlus对象。可以把它看作是AWT中的Graphics对象。

ImageProcessor ip = imp.getProcessor();
ip.setColor(Color.BLUE);
ip.setLineWidth(4);
ip.drawRect(10, 10, imp.getWidth() - 20, imp.getHeight() - 20);

3.4. Displaying an Image

3.4.显示一个图像

You only need to call show() method of ImagePlus object:

你只需要调用show()对象的ImagePlus方法。

imp.show();

4. OpenIMAJ

4.开放式玛格丽特

OpenIMAJ is set of Java libraries focused not only on computer vision and video processing but also machine learning, audio processing, working with Hadoop and much more. All parts of the OpenIMAJ project can be found here, under “Modules.” We need only the image processing part.

OpenIMAJ是一套Java库,不仅专注于计算机视觉和视频处理,还包括机器学习、音频处理、与Hadoop一起工作等等。OpenIMAJ项目的所有部分都可以在这里,在 “模块 “下找到。我们只需要图像处理部分。

4.1. Maven Dependency

4.1.Maven的依赖性

To start working with OpenIMAJ, simply add a dependency to your project’s <em>pom.xml</em> file:

要开始使用OpenIMAJ,只需在你项目的pom.xml文件中添加一个依赖关系。

<dependency>
    <groupId>org.openimaj</groupId>
    <artifactId>core-image</artifactId>
    <version>1.3.5</version>
</dependency>

You will find the latest release here.

你可以在这里找到最新的版本

4.1. Loading an Image

4.1.加载一个图像

To load an image, use ImageUtilities.readMBF() method:

要加载一个图像,使用ImageUtilities.readMBF()方法。

MBFImage image = ImageUtilities.readMBF(new File("path/to/your/image.jpg"));

MBF stands for the multiband floating-point image (RGB in this example, but it’s not the only way to represent colors).

MBF代表多波段浮点图像(本例中为RGB,但它不是表示颜色的唯一方法)。

4.2. Editing an Image

4.2.编辑一个图像

To draw the rectangle, we need to define its shape which is polygon consisting of 4 points (top left, bottom left, bottom right, top right):

为了绘制矩形,我们需要定义其形状,即由4个点(左上、左下、右下、右上)组成的多边形。

Point2d tl = new Point2dImpl(10, 10);
Point2d bl = new Point2dImpl(10, image.getHeight() - 10);
Point2d br = new Point2dImpl(image.getWidth() - 10, image.getHeight() - 10);
Point2d tr = new Point2dImpl(image.getWidth() - 10, 10);
Polygon polygon = new Polygon(Arrays.asList(tl, bl, br, tr));

As you might have noticed, in image processing Y-axis is reversed. After defining the shape, we need to draw it:

你可能已经注意到,在图像处理中,Y轴是反向的。在定义了形状之后,我们需要绘制它。

image.drawPolygon(polygon, 4, new Float[] { 0f, 0f, 255.0f });

Drawing method takes 3 arguments: shape, line thickness and RGB channel values represented by Float array.

绘制方法需要3个参数:形状、线条粗细和用Float数组表示的RGB通道值。

4.3. Displaying an Image

4.3.显示一个图像

We need to use DisplayUtilities:

我们需要使用DisplayUtilities

DisplayUtilities.display(image);

5. TwelveMonkeys ImageIO

5.TwelveMonkeys ImageIO

The TwelveMonkeys ImageIO library is intended as an extension to the Java ImageIO API, with support for a larger number of formats.

TwelveMonkeys ImageIO库旨在作为Java ImageIO API的扩展,支持更多格式。

Most of the time, the code will look the same as the built-in Java code, but it will function with additional image formats, after adding the necessary dependencies.

大多数时候,代码看起来与内置的Java代码相同,但在添加了必要的依赖性后,它将在额外的图像格式下发挥作用。

By default, Java supports only these five formats for images: JPEG, PNG, BMP, WEBMP, GIF.

默认情况下,Java只支持这五种格式的图像。JPEG,PNG,BMP,WEBMP,GIF

If we attempt to work with an image file in a different format, our application will not be able to read it and will throw a NullPointerException when accessing the BufferedImage variable.

如果我们试图处理一个不同格式的图像文件,我们的应用程序将无法读取它,并在访问BufferedImage变量时抛出一个NullPointerException

TwelveMonkeys adds supports for the following formats: PNM, PSD, TIFF, HDR, IFF, PCX, PICT, SGI, TGA, ICNS, ICO, CUR, Thumbs.db, SVG, WMF.

TwelveMonkeys增加了对以下格式的支持。PNM, PSD, TIFF, HDR, IFF, PCX, PICT, SGI, TGA, ICNS, ICO, CUR, Thumbs.db, SVG, WMF.

To work with images in a specific format, we need to add the corresponding dependency, such as imageio-jpeg or imageio-tiff.

要处理特定格式的图像,我们需要添加相应的依赖项,例如imageio-jpegimageio-tiff

You can find the full list of dependencies in the TwelveMonkeys documentation.

你可以在TwelveMonkeys 文档中找到完整的依赖项列表。

Let’s create an example that reads a .ico image. The code will look the same as the AWT section, except we will open a different image:

让我们创建一个读取.ico图片的例子。代码将与AWT部分相同,只是我们将打开一个不同的图像。

String imagePath = "path/to/your/image.ico";
BufferedImage myPicture = ImageIO.read(new File(imagePath));

For this example to work, we need to add the TwelveMonkeys dependency that contains support for .ico images, which is the imageio-bmp dependency, along with the imageio-core dependency:

为了让这个例子发挥作用,我们需要添加包含对.ico图像支持的TwelveMonkeys依赖项,也就是imageio-bmp依赖项,以及imageio-core依赖项。

<dependency>
    <groupId>com.twelvemonkeys.imageio</groupId>
    <artifactId>imageio-bmp</artifactId>
    <version>3.3.2</version>
</dependency>
<dependency>
    <groupId>com.twelvemonkeys.imageio</groupId>
    <artifactId>imageio-core</artifactId>
    <version>3.3.2</version>
</dependency>

And this is all! The built-in ImageIO Java API loads the plugins automatically at runtime. Now our project will work with .ico images as well.

这就是全部!内置的ImageIO Java API在运行时自动加载插件。现在我们的项目也可以使用.ico图片。

6. Summary

6.总结

You have been introduced to 4 libraries that can help you work with images. Going further, you might want to look for some image processing algorithms, like extracting edges, enhancing contrast, using filters or face detection.

我们已经向你介绍了4个可以帮助你处理图像的库。进一步说,你可能想寻找一些图像处理算法,如提取边缘、增强对比度、使用过滤器或脸部检测。

For those purposes, it might be better to start learning ImageJ or OpenIMAJ. Both are easy to include in a project and are much more powerful than AWT regarding image processing.

为了这些目的,开始学习ImageJ或OpenIMAJ可能会更好。两者都很容易包含在一个项目中,而且在图像处理方面比AWT强大得多。

These image processing examples can be found in the GitHub project.

这些图像处理实例可以在GitHub项目中找到。