Pregunta

¿Existe una biblioteca Java para rotar archivos JPEG en incrementos de 90 grados, sin incurrir en degradación de la imagen?

Otros consejos

Sobre la base de la respuesta de Henry, he aquí un ejemplo de cómo usar MediaUtil para llevar a cabo la rotación sin pérdida JPEG basado en los datos EXIF:

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
    ...
}

Con respecto al problema de que los datos EXIF ​​no necesariamente se manejan correctamente, ya que los datos EXIF ​​son irrelevantes en muchas situaciones, aquí hay un código de ejemplo que demuestra solo la función de rotación JPEG sin pérdidas de LLJTran (gracias al usuario113215):

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(); 
}

Si haces la entrada y salida File Los objetos se refieren al mismo archivo, puede ejecutar esto una y otra vez y observar que la imagen no se degrada, sin importar cuántas iteraciones se realice.

No es necesario una biblioteca externa para este tipo de cosas, todo está integrado en SE. El ser la función más fácil rotate () del objeto Graphics2D.

Por ejemplo:

   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();

ninguna pérdida!

O, si se quiere ser muy cuidadoso, sólo tiene que utilizar BufferedImage.getRGB (x, y), y traducirlo pixel por pixel a la nueva imagen.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top