Using ImageIO to convert from JPEG2000 to PNG - java

I'm trying to convert a JPEG2000 (.jp2) image to other formats (JPEG or PNG), so I try to use write method of javax.imageio package. This works fine for other formats (eg. JPEG to PNG), but when it comes to JPEG2000 (or TIFF) it throws an exception. Could anyone tell me what are the possible formats of the input image?
Exception in thread "main" java.lang.IllegalArgumentException: im == null!
at javax.imageio.ImageIO.write(ImageIO.java:1457)
at javax.imageio.ImageIO.write(ImageIO.java:1565)
at decodeincodeimages.AndroidInterface.convertFormat(AndroidInterface.java:199)
at Main_package.Execute.main(Execute.java:69)
Java Result: 1
And this is the method:
public static boolean convertFormat(String inputImagePath,
String outputImagePath, String formatName) throws IOException {
FileInputStream inputStream = new FileInputStream(inputImagePath);
FileOutputStream outputStream = new FileOutputStream(outputImagePath);
// reads input image from file
BufferedImage inputImage = ImageIO.read(inputStream);
// writes to the output image in specified format
boolean result = ImageIO.write(inputImage, formatName, outputStream);
// needs to close the streams
outputStream.close();
inputStream.close();
return result;
}
And I call it like this:
System.out.println(AndroidInterface.convertFormat("g:\\picture.jp2","g:\\conv.gif", "gif"));

ImageIO comes with the following formats built in: BMP, GIF, JPEG, PNG, WBMP (source: the API documentation). If you try to read an image in a different format, the ImageIO.read(...) methods will simply return null, which is why you get the IllegalArgumentException: im == null later in your method.
However, ImageIO also uses a plugin mechanism (service provider interface, or SPI), to allow for extra or third-party plugins to be installed.
To be able to read JPEG2000 or TIFF, you need such a plugin.
For JPEG2000 the best option is probably JAI. JAI also has a TIFF plugin. JAI was developed by Sun (now Oracle), but unfortunately, there hasn't been updates and bug fixes for years.
There's also Java bindings for OpenJPEG that should contain an ImageIO plugin for JPEG2000.
For TIFF you can also use my TwelveMonkeys ImageIO TIFF plugin. TwelveMonkeys does not currently have a JPEG2000 plugin, so it might be less useful for you.
(This list is not exhaustive, Google might help you find more :-) )
PS: From Java 9 (JEP-262) and later, TIFF format support is also built in.

You can use imageio-openjpeg as plugin for the ImageIO API. (https://github.com/dbmdz/imageio-jnr)

Related

Dealing with Adobe CMYK jpegs and Bufferedimage in java

Im trying to apply the code posted in this post:
How to convert from CMYK to RGB in Java correctly?
The Answer from the guy named Codo works for me so far, but my source is not a file, its an object that gets converted into a BufferedImage with
stream = (PRStream)object;
PdfImageObject image = new PdfImageObject(stream);
//this does not work
BufferedImage bi = image.getBufferedImage();
The guy has a method that returns a BufferedImage from a file like so
public BufferedImage readImage(File file) throws IOException, ImageReadException
but i want to use
BufferedImage bi = readImage(image.getBufferedImage());
instead of
File f = new File("/Users/adlib/Documents/projekte/pdf_compress/envirement/eclipse_luna/WORKSPACE/PDFCompression/src/Bild.jpg");
BufferedImage bi = readImage(f);
cause im ectracting all the images from a pdf file using iText.
I messed around with the code (changed file to BufferedImage and added streams) but a just dont get it to work. The File as Input image works fine, but not really what i need. What do i need to change to get This guys code to work with BufferedImage as input for the readImage() method?
Here is the complete code of this guy
https://stackoverflow.com/a/12132630/4944643
He uses Sanselan / Apache Commons Imaging
I'm not sure how iText extracts images, but chances are good it's using ImageIO. If so, you can just install (or depend on, using Maven) the TwelveMonkeys JPEG ImageIO plugin, and
BufferedImage bi = image.getBufferedImage();
...should just work.
The above mentioned plugin does support CMYK (and Adobe YCCK) JPEGs.
If iText doesn't use ImageIO, the above won't work (ie. when you already have a BufferedImage, it's too late to make the correct conversion). You will instead need to get to the bytes of the underlying PDF (using the getImageAsBytes() method), and use ImageIO (via the TwelveMonkeys JPEG plugin) to decode it:
byte[] imgBytes = image.getImageAsBytes();
BufferedImage bi = ImageIO.read(new ByteArrayInputStream(imgBytes));

Update Tiff-Metadata using Apache Commons-Imaging/Sanselan

I will modify and add Tiff-Tags to existing tif-files with java. JAI imageio crashed, because it could not deal with certain tags from Tiff 6.0. Apache Commons-Imaging seems to be able to deal with these tags. But I have no idea, how to do that. I found a post here, I used for beginning (How to embed ICC_Profile in TiffOutputSet).
Using the example code creates an image, which I can't open because of an LZW error. If I use the Imaging.writeImage(...) methods, It changes the color model from 8Bit to 24Bit and the Exif metadata hase gone.
What i have done is:
bufferedImage = Imaging.getBufferedImage(srcTiff);
byte[] imageBytes = Imaging.writeImageToBytes(tifFile, imageFormat, optional_params)
exifDirectory = tiffOutputSet.getOrCreateRootDirectory();
...
TiffImageWriterLossLess lossLessWriter = new TiffImageWriterLossless(imageBytes);
os = new FileOutputStream(tmpFile);
os = new BufferedOutputStream(os);
lossLessWriter.writeImage(bufferedImage, os, image_params);
Playing around with image_params, like compression or defining the outputset as params, results in different issues. But one is constant, the destImage is bigger then the src image, even when the source image is 24 bit like the dest image.
How could I get Commons-Imaging work for me?
I can respond to the destImage bigger than the src, it is because TIFF images have a compression that is not carried over when the image is read into memory. On writing the image back to storage, you must apply the compression explicitly.

What is the difference between using IOUtils and ImageIO for writing an image file

I have a tiff image stored as Base64 encoded String in a file. My aim is to create a tiff file out of it. This is what I am doing:
String base64encodedTiff = IOUtils.toString(new FileInputStream("C:/tiff-attachment.txt"));
byte[] imgBytes = DatatypeConverter.parseBase64Binary(base64encodedTiff);
BufferedImage bufImg = ImageIO.read(new ByteArrayInputStream(imgBytes));
ImageIO.write(bufImg, "tiff", new File("c:/new-darksouls-imageIO-tiff.tiff"));
ImageIO.write() is throwing IllegalArgumentException because bufImg is null. I don't understand what am I doing wrong here.
On the contrary if I use IOUtils to write, it works fine:
IOUtils.write(imgBytes, new FileOutputStream("c:/new-darksouls-io-tiff.tiff"));
Please help me understand
Why ImageIO is throwing exception
What is the right API and way for what I am trying to achieve.
ImageIO would be useful if, for example, you wanted to convert a PNG to a JPEG. Since you don't need to manipulate the image or convert to another format, don't bother with ImageIO. Just use IOUtils.write() to save the TIFF data verbatim.
ImageIO.read() is returning a null image because it can't read the TIFF file, probably because TIFF isn't one of the standard ImageIO plugin formats. The standard supported image formats are listed here:
http://docs.oracle.com/javase/6/docs/api/javax/imageio/package-summary.html
An additional note -- the code you posted buffers the entire image in memory. If you're concerned about using memory efficiently, consider using some kind of Base64 decoding input stream to perform the decoding on the fly. That might look like this:
try (FileOutputStream out = new FileOutputStream("c:/new-darksouls-io-tiff.tiff");
FileInputStream in = new FileInputStream("C:/tiff-attachment.txt");
Base64InputStream decodedIn = new Base64InputStream(in)) {
IOUtils.copy(decodedIn, out);
}

How to read an ico format picture in java?

I have a lot of .ico formatted pictures, and I want to use them in my Java SE project, but it doesn't know the format. How can I work around this?
Try out image4j - Image Library for Java
The image4j library allows you to read and write certain image formats
in 100% pure Java.
Currently the following formats are supported:
BMP (Microsoft bitmap format - uncompressed; 1, 4, 8, 24 and 32 bit)
ICO (Microsoft icon format - 1, 4, 8, 24 and 32 bit [XP uncompressed,
Vista compressed])
With the library you can easily decode your ico file
List<BufferedImage> image = ICODecoder.read(new File("input.ico"));
Apache Commons Imaging allows to read and write ICO files:
List<BufferedImage> images = Imaging.getAllBufferedImages(new File("input.ico"));
It supports several popular formats of metadata too (EXIF, IPTC and XMP).
TwelveMonkeys ImageIO allows to extend the ImageIO API to support ICO and numerous other image file formats.
Hint for reading ico files with Apache Commons Imaging 1.0-alpha2:
There seems to be a difference in between reading ico files as a file and reading ico files as a byte[]: Imaging.getAllBufferedImages(File) reads an ico file, Imaging.getAllBufferedImages(new ByteArrayInputStream(byte[] icoFileContent, yourIcoFilename) also reads the ico file. Imaging.getAllBufferedImages(byte[]) does not read the same ico file but throws an ImageReadException. See code below.
File icoFile = new File("bluedot.ico");
// Works fine
List<BufferedImage> images = Imaging.getAllBufferedImages(icoFile);
Assert.assertFalse(images.isEmpty());
ImageIO.write(images.get(0), "png", new File("bluedot.png"));
// Also works fine
byte[] icoFileContent = Files.readAllBytes(icoFile.toPath());
images = Imaging.getAllBufferedImages(new ByteArrayInputStream(icoFileContent), "bluedot.ico");
Assert.assertFalse(images.isEmpty());
ImageIO.write(images.get(0), "png", new File("bluedot2.png"));
// Throws an exception
images = Imaging.getAllBufferedImages(icoFileContent);
Additionally here is a guide how I created the .ico file that is not readable by Apache Commons Imaging 1.0-alpha2 as byte[] (but is readable as File and is readable as ByteArrayInputStream):
Start GIMP (in my case version 2.10.22)
Window menu "File" > "New..."
Template: [empty]
Width: 48px
Height: 48px
Leave the rest as is (see screenshot below)
Draw something (e.g. a blue dot)
Window menu "File" > "Export as..."
File name: "bluedot.ico"
Icon Details: "4 bpp, 1-bit alpha, 16-slot palette"
Compressed (PNG): Not checked
Click "Export"
Imaging.getAllBufferedImages(byte[]) will throw org.apache.commons.imaging.ImageReadException: Can't parse this format.
Imaging.getAllBufferedImages(File) will read this file.

Java Exception: New BMP version not implemented yet

I converted image with help of GIMP to RGB565.
Now I want to read this bmp-image in java:
BufferedImage bufImg = ImageIO.read(imagePathFile);
but it throws exception:
java.lang.RuntimeException: New BMP version not implemented yet
What should I do to read this image?
You could try JAI or Apache Sanselan.
Note that JAI requires some native libraries to be plugged into the JVM whereas Sanselan won't read JPEG images and thus requires you to fall back to ImageIO or even JPEGImageDecoder for those.

Categories

Resources