I was given the following code, and Eclipse marked it (at the JPEGImageEncoder line) as an error (Access restriction). I changed Eclipse options to make that code compile, but I read that the error means that that class (JPEGImageEncoder) may not be implemented by some JRE implementation (not a Sun/Oracle one).
So, what should be the code that wouldn't have access restrictions, i.e. completely safe code to do the same thing (create a JPG image)?
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(filename));
JPEGImageEncoder encoder=JPEGCodec.createJPEGEncoder(out);
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(buffImage);
param.setQuality(0.8f, false);
encoder.encode(buffImage, param);
Maybe I've misunderstood, but if all you're looking to do is save a BufferedImage object as a jpeg, you can do this (from Java 1.4 onwards):
ImageIO.write(bufferedImage,"jpg",file);
Here's a link with more information: http://download.oracle.com/javase/tutorial/2d/images/saveimage.html
As you can see, it says that JPEG, PNG, GIF, BMP and WBMP will always be supported.
If you want to set the compression/quality, it's a little more work but not too much. Assuming you have a bufferedImage and an outFile:
IIOImage outputImage = new IIOImage(bufferedImage, null, null);
ImageWriter writer = ImageIO.getImageWritersByFormatName("jpeg").next();
writer.setOutput(new FileImageOutputStream(outFile));
ImageWriteParam writeParam = writer.getDefaultWriteParam();
writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
writeParam.setCompressionQuality(.75f); // float between 0 and 1, 1 for max quality.
writer.write( null, outputImage, writeParam);
(fixed from previous answer)
Related
I want to compress(reduce) image size using Java. We can upload images in jpg/jpeg/png formats. The general format of images is PNG. So, after image uploaded to the server, we need to compress(reduce file size) and convert it to PNG.
I have the next code for the compress image:
BufferedImage bufferedImage = ImageIO.read(inputStream);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
switch (imageType) {
case PNG:
case JPG:
// need Java 9+ for PNG writer support
ImageWriter writer = ImageIO.getImageWritersByFormatName(imageType.getExtension()).next();
ImageOutputStream ios = ImageIO.createImageOutputStream(outputStream);
writer.setOutput(ios);
ImageWriteParam param = writer.getDefaultWriteParam();
if (param.canWriteCompressed()) {
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(0.3f);
}
writer.write(null, new IIOImage(bufferedImage, null, null), param);
writer.dispose();
return new ByteArrayInputStream(outputStream.toByteArray());
default:
log.warn("Image type unknown");
return null;
}
The problem is - after processing the image, I got the result - file size increased instead of reducing. The original image has a lower size than compressed.
Any suggestions on how to solve this issue?
Unfortunately the lossy JPEG compression compresses far better than the lossless PNG compression. You could restrict width and height of the image and scale proportionally.
So I would switch to JPEG and restrict the size.
As a solution for this problem I can recommend the API of TinyPNG.
You can use it for compressing as well as resizing the image.
It works for both .jpeg and .png.
Documentation: tinypng.com/developers/reference/java
I'm a beginner in Java and a geomatics student.
I'am using IntelliJ.
I would like to create a TIFF from a BufferedImage.
This is my code :
byte[] buffer = new byte[width * height];
ColorSpace cs = ColorSpace.getInstance( ColorSpace.CS_GRAY );
int[] nBits = { 8 };
ColorModel cm = new ComponentColorModel( cs, nBits, false, true,Transparency.OPAQUE, DataBuffer.TYPE_BYTE );
SampleModel sm = cm.createCompatibleSampleModel( width, height );
DataBufferByte db = new DataBufferByte( buffer, width * height );
WritableRaster raster = Raster.createWritableRaster( sm, db, null);
BufferedImage result = new BufferedImage( cm, raster, false , null );
File outputfile = new File( "saved.png" );
ImageIO.write( result, "png", outputfile );
A raster .png is create and it works well. But I want to create a .TIFF and ImageIO.write don't create TIFF (only png,bmp and jpeg). So I download the JAI (Java Advanced Imaging) here : http://download.java.net/media/jai/builds/release/1_1_3/
I upload it on my project and on Maven, but I don't know how to make a tiff simply... I try some snippets that I found on the internet but it don't work..
TIFFEncodeParam params = new TIFFEncodeParam();
FileOutputStream os = new FileOutputStream("PingsTiff.tiff");
javax.media.jai.JAI.create("encode", result, os, "TIFF", params);
The "TIFFEncodeParam" and "media" is not recognized...and I'm a real noob at programming..
Thanks
First of all, JAI comes with a set of ImageIO plugins, that will allow you to use ImageIO.write to write in TIFF format. But it requires the jai_imageio.jar to be on class path. I guess this is the JAR you are missing.
Also, the code you posted should work, if you have the imports and dependencies set up correctly. It's a little tricky because some parts of JAI requires native libraries that needs to be installed using the installer, and in the correct JRE, etc. Because of this, it's not a perfect fit with Maven (although certainly doable).
However, as you see from the download link in your question, JAI is a pretty much dead project (the latest update is from 2006).
Because of this lack of updates, bug fixes and support, along with the native parts and the license issues, I set up an open source project, aimed to provide at least as good file format support as JAI, with no native requirements and released under BSD license.
You can read about it, and the TIFF plugin in particular at the project home page. A little further down the page is down is download links, Maven dependency information etc.
When you have declared dependency on the TIFF plugin, you should be able to write your TIFF using plain ImageIO like this:
File outputfile = new File("saved.tif");
if (!ImageIO.write(result, "TIFF", outputfile)) {
// Beware, write is a boolean method, that returns success!
System.err.println("Could not write " + outputfile.getAbsolutePath() + " in TIFF format.");
}
I was making an application that hides data in LSBs of a JPEG image. Knowing that JPEG is a lossy compression and has a default compression of 70%, I changed it's parameters to 100% thus assuming that it wont destroy any data in the image. Here is the code.
File output = new File(gui.getOutput()+".jpg");
ImageWriter jpgWriter = ImageIO.getImageWritersByFormatName("jpg").next();
ImageWriteParam jpgWriteParam = jpgWriter.getDefaultWriteParam();
jpgWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
jpgWriteParam.setCompressionQuality(1f);
FileImageOutputStream outputStream = new FileImageOutputStream(output);
jpgWriter.setOutput(outputStream);
IIOImage outputImage = new IIOImage(image, null, null);
jpgWriter.write(null, outputImage, jpgWriteParam);
jpgWriter.dispose();
The image that was created was indeed loss less, but the data I stored within the pixels were destroyed. (I checked it by reading the inserted data in the LSB and it wasn't the data I stored in the image).
What should I do to avoid the data being destroyed?
A must read api, and it only applies to quantization step
I am currently working with Image processing in Java. Initially I used ImageIO class to write images
ImageIO.write(image,"jpg",os);
the problem with this method is am lossing the actual image size and quality. Then I preferred ByteStream
Files.readAllBytes(fi.toPath());
to read and
fos.write(fileContent);
to write Images. This works perfectly. The issue I am facing here is I can read only files but not Images(ie, BuffreredImage image). Is it possible to read a Image rather than files here or should I move to someother IO?
Code Snippet is here,
try {
File fnew=new File("d:\\3\\IMG1.jpg");
java.io.FileOutputStream fos = new java.io.FileOutputStream(new File("d:\\3\\Test1\\4.jpg"));
File fi = new File("d:\\3\\7.jpg");
byte[] fileContent = Files.readAllBytes(fi.toPath());
fos.write(fileContent);
} catch (Exception e) {
System.out.println("Exception");
}
Any Kind of suggestions or help will be appreciated. Thanks in Advance.
the problem with this method is am lossing the actual image size and quality. Then I preferred ByteStream
When you read a JPEG with with ImageIO, it is converting the JPEG to a Bitmap automatically. Then when you write it, it is encoding to a JPEG again (which loses quality).
Just replace ImageIO.write(image,"jpg",os) with ImageIO.write(image,"png",os) and you are done. A lossless format such as PNG will not lose any data when you write the image.
BufferedImage getRGB() will get you all the actual pixel data for the image. There will be no compression or anything like JPEG. It will be the raw image.
Edited to add an example based on my comments...
BufferedImage image = ImageIO.read(new File("google.jpg"));
ImageWriter w = ImageIO.getImageWritersBySuffix("jpg").next();
ImageOutputStream out = ImageIO.createImageOutputStream(new File("output.jpg"));
w.setOutput(out);
ImageWriteParam param = new JPEGImageWriteParam(Locale.getDefault());
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(1);
w.write(null, new IIOImage(image, null, null), param);
out.close();
I'm trying to convert a bitmap image into an uncompressed tif file for use with the Tesseract OCR engine.
I can use this method to produce a compressed tif file...
final BufferedImage bmp = ImageIO.read(new File("input.bmp"));
ImageIO.write(bmp, "jpg", new File("output.tif"));
This produces an empty tif file when the "jpg" is changed to tif as these files are dealt with in Java Advanced Imaging (JAI).
How can I create an uncompressed tif image? Should I decompress the tif image produced from the above code or is there another way to handle the conversion process?
Any examples provided would be much appreciated.
Thanks
kingh32
You can use ImageWriteParam to disable compression:
TIFFImageWriterSpi spi = new TIFFImageWriterSpi();
ImageWriter writer = spi.createWriterInstance();
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_DISABLED);
ImageOutputStream ios = ImageIO.createImageOutputStream(new File("output.tif"));
writer.setOutput(ios);
writer.write(null, new IIOImage(bmp, null, null), param);
Some time before i was facing the problems with tiff images reading and conversion with jai.
I found that it need to install support for working with tiff images in jai, then it works fine for me u can also get it form here:
https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/ViewProductDetail-Start?ProductRef=jaiio-1.0_01-oth-JPR#CDS-CDS_Developer
and install over a jvm then it will also work for you.
you can also have a look here
Java / JAI - save an image gray-scaled