Latest release is TwelveMonkeys ImageIO 3.5 (Jan. 22nd, 2020). Release notes.
TwelveMonkeys ImageIO is a collection of plugins and extensions for Java's ImageIO.
These plugins extends the number of image file formats supported in Java, using the javax.imageio.* package. The main purpose of this project is to provide support for formats not covered by the JRE itself.
Support for formats is important, both to be able to read data found "in the wild", as well as to maintain access to data in legacy formats. Because there is lots of legacy data out there, we see the need for open implementations of readers for popular formats. The goal is to create a set of efficient and robust ImageIO plug-ins, that can be distributed independently.
Mainstream format support
ICC_PROFILE
segmentsjavax_imageio_jpeg_image_1.0
format (currently as native format, may change in the future)javax_imageio_jpeg_image_1.0
format)If you are one of the authors, or know one of the authors and/or the current license holders of either the original jj2000 package or the JAI ImageIO project, please contact me (I've tried to get in touch in various ways, without success so far).
Alternatively, if you have or know of a JPEG-2000 implementation in Java with a suitable license, get in touch.
Legacy formats
float
) and normalized using a global tone mapper by default.
readRaster
Icon/other formats
sips
command line tool)Other formats, using 3rd party libraries
Important note on using Batik: Please read The Apache™ XML Graphics Project - Security, and make sure you use either version 1.6.1, 1.7.1 or 1.8+.
Most of the time, all you need to do is simply include the plugins in your project and write:
BufferedImage image = ImageIO.read(file);
This will load the first image of the file, entirely into memory.
The basic and simplest form of writing is:
if (!ImageIO.write(image, format, file)) {
// Handle image not written case
}
This will write the entire image into a single file, using the default settings for the given format.
The plugins are discovered automatically at run time. See the FAQ for more info on how this mechanism works.
If you need more control of read parameters and the reading process, the common idiom for reading is something like:
// Create input stream
ImageInputStream input = ImageIO.createImageInputStream(file);
try {
// Get the reader
Iterator<ImageReader> readers = ImageIO.getImageReaders(input);
if (!readers.hasNext()) {
throw new IllegalArgumentException("No reader for: " + file);
}
ImageReader reader = readers.next();
try {
reader.setInput(input);
// Optionally, listen for read warnings, progress, etc.
reader.addIIOReadWarningListener(...);
reader.addIIOReadProgressListener(...);
ImageReadParam param = reader.getDefaultReadParam();
// Optionally, control read settings like sub sampling, source region or destination etc.
param.setSourceSubsampling(...);
param.setSourceRegion(...);
param.setDestination(...);
// ...
// Finally read the image, using settings from param
BufferedImage image = reader.read(0, param);
// Optionally, read thumbnails, meta data, etc...
int numThumbs = reader.getNumThumbnails(0);
// ...
}
finally {
// Dispose reader in finally block to avoid memory leaks
reader.dispose();
}
}
finally {
// Close stream in finally block to avoid resource leaks
input.close();
}
Query the reader for source image dimensions using reader.getWidth(n)
and reader.getHeight(n)
without reading the
entire image into memory first.
It's also possible to read multiple images from the same file in a loop, using reader.getNumImages()
.
If you need more control of write parameters and the writing process, the common idiom for writing is something like:
// Get the writer
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(format);
if (!writers.hasNext()) {
throw new IllegalArgumentException("No writer for: " + format);
}
ImageWriter writer = writers.next();
try {
// Create output stream
ImageOutputStream output = ImageIO.createImageOutputStream(file);
try {
writer.setOutput(output);
// Optionally, listen to progress, warnings, etc.
ImageWriteParam param = writer.getDefaultWriteParam();
// Optionally, control format specific settings of param (requires casting), or
// control generic write settings like sub sampling, source region, output type etc.
// Optionally, provide thumbnails and image/stream metadata
writer.write(..., new IIOImage(..., image, ...), param);
}
finally {
// Close stream in finally block to avoid resource leaks
output.close();
}
}
finally {
// Dispose writer in finally block to avoid memory leaks
writer.dispose();
}
For more advanced usage, and information on how to use the ImageIO API, I suggest you read the Java Image I/O API Guide from Oracle.
Because the ImageIO
plugin registry (the IIORegistry
) is "VM global", it doesn't by default work well with
servlet contexts. This is especially evident if you load plugins from the WEB-INF/lib
or classes
folder.
Unless you add ImageIO.scanForPlugins()
somewhere in your code, the plugins might never be available at all.
In addition, servlet contexts dynamically loads and unloads classes (using a new class loader per context).
If you restart your application, old classes will by default remain in memory forever (because the next time
scanForPlugins
is called, it's another ClassLoader
that scans/loads classes, and thus they will be new instances
in the registry). If a read is attempted using one of the remaining "old" readers, weird exceptions
(like NullPointerException
s when accessing static final
initialized fields or NoClassDefFoundError
s
for uninitialized inner classes) may occur.
To work around both the discovery problem and the resource leak,
it is strongly recommended to use the IIOProviderContextListener
that implements
dynamic loading and unloading of ImageIO plugins for web applications.
<web-app ...>
...
<listener>
<display-name>ImageIO service provider loader/unloader</display-name>
<listener-class>com.twelvemonkeys.servlet.image.IIOProviderContextListener</listener-class>
</listener>
...
</web-app>
Loading plugins from WEB-INF/lib
without the context listener installed is unsupported and will not work correctly.
The context listener has no dependencies to the TwelveMonkeys ImageIO plugins, and may be used with JAI ImageIO or other ImageIO plugins as well.
Another safe option, is to place the JAR files in the application server's shared or common lib folder.
The library comes with a resampling (image resizing) operation, that contains many different algorithms to provide excellent results at reasonable speed.
import com.twelvemonkeys.image.ResampleOp;
...
BufferedImage input = ...; // Image to resample
int width, height = ...; // new width/height
BufferedImageOp resampler = new ResampleOp(width, height, ResampleOp.FILTER_LANCZOS); // A good default filter, see class documentation for more info
BufferedImage output = resampler.filter(input, null);
The library comes with a dithering operation, that can be used to convert BufferedImage
s to IndexColorModel
using
Floyd-Steinberg error-diffusion dither.
import com.twelvemonkeys.image.DiffusionDither;
...
BufferedImage input = ...; // Image to dither
BufferedImageOp ditherer = new DiffusionDither();
BufferedImage output = ditherer.filter(input, null);
Download the project (using Git):
$ git clone git@github.com:haraldk/TwelveMonkeys.git
This should create a folder named TwelveMonkeys
in your current directory. Change directory to the TwelveMonkeys
folder, and issue the command below to build.
Build the project (using Maven):
$ mvn package
Currently, the recommended JDK for making a build is Oracle JDK 7.x or 8.x.
It's possible to build using OpenJDK, but some tests might fail due to some minor differences between the color management systems used. You will need to either disable the tests in question, or build without tests altogether.
Because the unit tests needs quite a bit of memory to run, you might have to set the environment variable MAVEN_OPTS
to give the Java process that runs Maven more memory. I suggest something like -Xmx512m -XX:MaxPermSize=256m
.
Optionally, you can install the project in your local Maven repository using:
$ mvn install
To install the plug-ins, either use Maven and add the necessary dependencies to your project, or manually add the needed JARs along with required dependencies in class-path.
The ImageIO registry and service lookup mechanism will make sure the plugins are available for use.
To verify that the JPEG plugin is installed and used at run-time, you could use the following code:
Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("JPEG");
while (readers.hasNext()) {
System.out.println("reader: " + readers.next());
}
The first line should print:
reader: com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReader@somehash
To depend on the JPEG and TIFF plugin using Maven, add the following to your POM:
...
<dependencies>
...
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-jpeg</artifactId>
<version>3.5</version>
</dependency>
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-tiff</artifactId>
<version>3.5</version>
</dependency>
<!--
Optional dependency. Needed only if you deploy `ImageIO` plugins as part of a web app.
Make sure you add the `IIOProviderContextListener` to your `web.xml`, see above.
-->
<dependency>
<groupId>com.twelvemonkeys.servlet</groupId>
<artifactId>servlet</artifactId>
<version>3.5</version>
</dependency>
</dependencies>
To depend on the JPEG and TIFF plugin in your IDE or program, add all of the following JARs to your class path:
twelvemonkeys-common-lang-3.5.jar
twelvemonkeys-common-io-3.5.jar
twelvemonkeys-common-image-3.5.jar
twelvemonkeys-imageio-core-3.5.jar
twelvemonkeys-imageio-metadata-3.5.jar
twelvemonkeys-imageio-jpeg-3.5.jar
twelvemonkeys-imageio-tiff-3.5.jar
Requires Java 7 or later.
Common dependencies
ImageIO dependencies
ImageIO plugins
ImageIO plugins requiring 3rd party libs
Photoshop Path support for ImageIO
Servlet support
Use this version for projects that requires Java 6 or need the JMagick support. Does not support Java 8 or later.
Common dependencies
ImageIO dependencies
ImageIO plugins
ImageIO plugins requiring 3rd party libs
Servlet support
The project is distributed under the OSI approved BSD license:
Copyright (c) 2008-2018, Harald Kuhr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
o Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
o Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
o Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
q: How do I use it?
a: The easiest way is to build your own project using Maven, and just add dependencies to the specific plug-ins you need. If you don't use Maven, make sure you have all the necessary JARs in classpath. See the Install section above.
q: What changes do I have to make to my code in order to use the plug-ins?
a: The short answer is: None. For basic usage, like ImageIO.read(...)
or ImageIO.getImageReaders(...)
, there is no need
to change your code. Most of the functionality is available through standard ImageIO APIs, and great care has been taken
not to introduce extra API where none is necessary.
Should you want to use very specific/advanced features of some of the formats, you might have to use specific APIs, like setting base URL for an SVG image that consists of multiple files, or controlling the output compression of a TIFF file.
q: How does it work?
a: The TwelveMonkeys ImageIO project contains plug-ins for ImageIO. ImageIO uses a service lookup mechanism, to discover plug-ins at runtime.
All you have have to do, is to make sure you have the TwelveMonkeys JARs in your classpath.
You can read more about the registry and the lookup mechanism in the IIORegistry API doc.
The fine print: The TwelveMonkeys service providers for JPEG, BMP and TIFF, overrides the onRegistration method, and
utilizes the pairwise partial ordering mechanism of the IIOServiceRegistry
to make sure it is installed before
the Sun/Oracle provided JPEGImageReader
and BMPImageReader
, and the Apple provided TIFFImageReader
on OS X,
respectively. Using the pairwise ordering will not remove any functionality form these implementations, but in most
cases you'll end up using the TwelveMonkeys plug-ins instead.
q: What about JAI? Several of the formats are already supported by JAI.
a: While JAI (and jai-imageio in particular) have support for some of the formats, JAI has some major issues. The most obvious being:
q: What about JMagick or IM4Java? Can't you just use what's already available?
a: While great libraries with a wide range of formats support, the ImageMagick-based libraries has some disadvantages compared to ImageIO.
We did it
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。