2010-05-17 31 views
2

J'essaie d'utiliser JAI pour effectuer une tâche de rotation sur une image. Je peux obtenir ce travail sans problème. Cependant, il y a une perte sévère de demi-tons dans l'image. L'image peut être tournée dans photoshop sans ce manque de contraste.L'utilisation de JAI pour faire pivoter une image en niveaux de gris augmente le contraste

Veuillez voir les 3 images suivantes empilées l'une à côté de l'autre ici, pour voir ce que je veux dire;

http://imgur.com/SYPhZ.jpg

L'image du haut est l'original, le milieu est tourné dans Photoshop pour prouver qu'il peut être fait, et le fond est le résultat de mon code.

Pour voir les images réelles, s'il vous plaît voir ici;

Avant rotate: http://imgur.com/eiAOO.jpg Après rotate: http://imgur.com/TTUKS.jpg

Vous pouvez voir le problème le plus clairement si vous chargez les images dans deux onglets différents, et flick entre eux.

En termes de code, je charge l'image comme suit;

public void testIt() throws Exception { 

    File source = new File("c:\\STRIP.jpg"); 
    FileInputStream fis = new FileInputStream(source); 
    BufferedImage sourceImage = ImageIO.read(fis); 
    fis.close(); 

    BufferedImage rotatedImage = doRotate(sourceImage, 15); 
    FileOutputStream output = new FileOutputStream("c:\\STRIP_ROTATED.jpg"); 
    ImageIO.write(rotatedImage, "JPEG", output); 

} 

puis voici la fonction de rotation;

public BufferedImage doRotate(BufferedImage input, int angle) { 
    int width = input.getWidth(); 
    int height = input.getHeight(); 


    double radians = Math.toRadians(angle/10.0); 

    // Rotate about the input image's centre 
    AffineTransform rotate = AffineTransform.getRotateInstance(radians, width/2.0, height/2.0); 

    Shape rect = new Rectangle(width, height); 

    // Work out how big the rotated image would be.. 
    Rectangle bounds = rotate.createTransformedShape(rect).getBounds(); 

    // Shift the rotated image into the centre of the new bounds 
    rotate.preConcatenate(
      AffineTransform.getTranslateInstance((bounds.width - width)/2.0, (bounds.height - height)/2.0)); 

    BufferedImage output = new BufferedImage(bounds.width, bounds.height, input.getType()); 
    Graphics2D g2d = (Graphics2D) output.getGraphics(); 

    // Fill the background with white 
    g2d.setColor(Color.WHITE); 
    g2d.fill(new Rectangle(width, height)); 

    RenderingHints hints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); 
    hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

    g2d.setRenderingHints(hints); 
    g2d.drawImage(input, rotate, null); 

    return output; 
} 

Répondre

1

Ceci est apparemment un bug dans qui existe JAI pendant un certain temps:

La première mention que j'ai pu trouver de cette question appears here. Cet article original pointe vers un old jai-core issue here. Après avoir lu cette résolution, il semble qu'il y ait un bogue racine encore ouvert et described here.

Que tout ce travail de détective soit pertinent ou non pour votre application, il peut être possible de construire un espace colorimétrique plus tolérant que la valeur par défaut utilisée par JAI pour votre code de test.

Dans le pire des cas, vous pouvez écrire vous-même la traversée des pixels pour créer une image pivotée. Ce n'est pas la solution optimale, mais je le mentionne pour l'exhaustivité si vous avez absolument besoin d'une solution à ce problème aujourd'hui.