1. Overview
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.
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.
2.1. Loading an Image
The first thing is to create a BufferedImage object from a picture saved on our disk drive:
String imagePath = "path/to/your/image.jpg";
BufferedImage myPicture = ImageIO.read(new File(imagePath));
2.2. Editing an Image
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.
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:
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
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:
JLabel picLabel = new JLabel(new ImageIcon(myPicture));
Then add our JLabel to JPanel, which we can treat as
of Java-based GUI: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 f = new JFrame();
f.setSize(new Dimension(myPicture.getWidth(), myPicture.getHeight()));
f.add(jPanel);
f.setVisible(true);
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.
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.
3.1. Maven Dependency
To start working with ImageJ, simply add a dependency to your project’s pom.xml file:
<dependency>
<groupId>net.imagej</groupId>
<artifactId>ij</artifactId>
<version>1.51h</version>
</dependency>
You will find the newest version in the Maven repository.
3.2. Loading an Image
To load the image, you need to use the openImage() static method, from IJ class:
ImagePlus imp = IJ.openImage("path/to/your/image.jpg");
3.3. Editing an Image
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 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
You only need to call show() method of ImagePlus object:
imp.show();
4. OpenIMAJ
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.
4.1. Maven Dependency
To start working with OpenIMAJ, simply add a dependency to your project’s pom.xml file:
<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
To load an image, use ImageUtilities.readMBF() method:
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).
4.2. Editing an Image
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):
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:
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.
4.3. Displaying an Image
We need to use DisplayUtilities:
DisplayUtilities.display(image);
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.
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.
By default, Java supports only these five formats for images: 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.
TwelveMonkeys adds supports for the following formats: 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.
You can find the full list of dependencies in the TwelveMonkeys documentation.
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:
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:
<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.
6. Summary
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.
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.
These image processing examples can be found in the GitHub project.