0

Any reason this code would changing the resolution of the original JPEG? I can understand if the file size were different because the JPEG quality settings are probably different but I don't understand why this would be resizing an image.

File newfile=new File(mydestinationfolder.concat(imagename));
Files.move(file.toPath(),newfile.toPath(), REPLACE_EXISTING);
Rotation Orientation;
if ((Orientation=Exif_data.get_Exif_Orientation(newfile)) != null) {

    System.out.println(Orientation.toString());
    BufferedImage oldimage = ImageIO.read(newfile);
    BufferedImage tmp = Scalr.rotate(oldimage, Orientation);
    oldimage.flush();
    oldimage=tmp;
    ImageIO.write(oldimage, "JPEG", newfile);

}
Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129
Codeguy007
  • 891
  • 1
  • 12
  • 32
  • The image size may change to allow for the entire picture to remain visible as it is rotated - that is, at 45 degrees with the width and height need to be changed to allow the contents of the image to be rendered – MadProgrammer Jun 11 '13 at 04:12
  • 1
    check if it is useful..http://stackoverflow.com/questions/4918482/rotating-bufferedimage-instances – vishal_aim Jun 11 '13 at 04:18
  • @MadProgrammer I think the Exif orientation can only multiples of 90deg. So, dimensions should only be flipped. – Harald K Jun 11 '13 at 12:00

2 Answers2

1

Well I am not sure why but the default settings for ImageIO.write() are changing the resolution. If I define a custom writer with JPEG quality set to 100%, the image resolution stays the same.

NOTE: output.close() at the end is important because as long as the stream is open the file is locked.

BufferedImage oldimage = ImageIO.read(newfile);
BufferedImage tmp = Scalr.rotate(oldimage, Orientation);
oldimage.flush();
oldimage=tmp;
Iterator iter = ImageIO.getImageWritersByFormatName("jpeg");
ImageWriter writer = (ImageWriter)iter.next();
ImageWriteParam iwp = writer.getDefaultWriteParam();
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
float quality=1.0f;
iwp.setCompressionQuality(quality);

FileImageOutputStream output = new FileImageOutputStream(newfile);
writer.setOutput(output);

IIOImage image = new IIOImage(oldimage, null, null);
writer.write(null, image, iwp);
writer.dispose();
output.close();
Codeguy007
  • 891
  • 1
  • 12
  • 32
1

Late answer, but anyway..

As a JPEG read/manipulate/write cycle using ImageIO is always going to be lossy, and all you are doing is rotating, you should have a look at LLJTran from mediautil, as mentioned in this thread.

With that package, you should be able to benefit from a special feature of JPEG block compression to do a lossless JPEG transformation.

Still don't understand why your original code would change the image resolution, nor why your proposed solution would fix it though... Sounds like a bug to me, and should be reported to Oracle. What I do know though, is that setting the JPEG quality to 1.0 (100%) isn't what JPEG was meant for, and is going to cause huge files with no gain in quality (it may possibly be worse than storing at the quality of the original) given the input is already a compressed JPEG .

Community
  • 1
  • 1
Harald K
  • 26,314
  • 7
  • 65
  • 111
  • Thanks haraldK! I will looking to mediautil. It's not too late as I need to improve the code. I guess it make sense that if I convert a file to JPEG for rotation that I could loose quality. I know JPEG is lossy and should have realized rotating this way would be lossy. – Codeguy007 Dec 20 '14 at 06:37