Java中的无损JPEG旋转(90/180/270度)?

是否有用于以90度为增量旋转JPEG文件的Java库,而不会导致图像质量下降?

我发现了这个: http : //mediachest.sourceforge.net/mediautil/

API: http : //mediachest.sourceforge.net/mediautil/javadocs/mediautil/image/jpeg/LLJTran.html

以Henry的答案为基础,这里是一个如何使用MediaUtil根据EXIF数据执行无损JPEG旋转的示例:

try { // Read image EXIF data LLJTran llj = new LLJTran(imageFile); llj.read(LLJTran.READ_INFO, true); AbstractImageInfo imageInfo = llj.getImageInfo(); if (!(imageInfo instanceof Exif)) throw new Exception("Image has no EXIF data"); // Determine the orientation Exif exif = (Exif) imageInfo; int orientation = 1; Entry orientationTag = exif.getTagValue(Exif.ORIENTATION, true); if (orientationTag != null) orientation = (Integer) orientationTag.getValue(0); // Determine required transform operation int operation = 0; if (orientation > 0 && orientation < Exif.opToCorrectOrientation.length) operation = Exif.opToCorrectOrientation[orientation]; if (operation == 0) throw new Exception("Image orientation is already correct"); OutputStream output = null; try { // Transform image llj.read(LLJTran.READ_ALL, true); llj.transform(operation, LLJTran.OPT_DEFAULTS | LLJTran.OPT_XFORM_ORIENTATION); // Overwrite original file output = new BufferedOutputStream(new FileOutputStream(imageFile)); llj.save(output, LLJTran.OPT_WRITE_ALL); } finally { IOUtils.closeQuietly(output); llj.freeMemory(); } } catch (Exception e) { // Unable to rotate image based on EXIF data ... } 

关于EXIF数据的问题不一定正确处理,因为EXIF数据在许多情况下无关紧要,这里的示例代码仅演示了LLJTran无损JPEG旋转function(感谢user113215):

 final File SrcJPEG = new File("my-input.jpg"); final File DestJPEG = new File("my-output.jpg"); final FileInputStream In = new FileInputStream(SrcJPEG); try { final LLJTran LLJT = new LLJTran(In); LLJT.read(LLJTran.READ_ALL, true); LLJT.transform(LLJTran.ROT_90); final FileOutputStream Out = new FileOutputStream(DestJPEG); try { LLJT.save(Out, LLJTran.OPT_WRITE_ALL); } finally { Out.close(); } } finally { In.close(); } 

如果你使输入和输出File对象引用同一个文件,你可以一遍又一遍地运行它,并观察图像不会降低,无论它经过多少次迭代。

你不需要外部库来做这种事情,它都是SE内置的。 最简单的是Graphics2D对象的rotate()函数。

例如:

  Image rotatedImage = new BufferedImage(imageToRotate.getHeight(null), imageToRotate.getWidth(null), BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = (Graphics2D) rotatedImage.getGraphics(); g2d.rotate(Math.toRadians(90.0)); g2d.drawImage(imageToRotate, 0, -rotatedImage.getWidth(null), null); g2d.dispose(); 

没有损失!

或者,如果您想要格外小心,只需使用BufferedImage.getRGB(x,y),并将其逐像素地转换为新图像。