47 votes

Échelle JAVA Meilleures pratiques en matière d'image

J'ai une question concernant l'image mise à l'échelle. J'ai une application dans laquelle les utilisateurs sont en mesure de télécharger des photos dans des albums, mais naturellement, les images téléchargées doivent être redimensionnées donc il y a aussi les pouces disponibles et sur les photos, s'inscrivent également dans la page (par exemple. 800x600). La façon dont je dois la redimensionner est comme ceci:

Image scaledImage = img.getScaledInstance((int)width, (int)height, Image.SCALE_SMOOTH);
BufferedImage imageBuff = new BufferedImage((int)width, (int)height, BufferedImage.TYPE_INT_RGB);
Graphics g = imageBuff.createGraphics();
g.drawImage(scaledImage, 0, 0, new Color(0,0,0), null);
g.dispose();

Et ça marche dans les clous. Mon seul problème est que le g.la méthode drawImage() semble être affreusement lent, et je ne peux pas imaginer à l'utilisateur d'être assez patient pour attendre un chargement de 20 images de 20*10 secondes à 3 minutes. En fait, sur mon ordinateur, il faut près de 40 secondes pour faire les 3 redimensionne pour une seule photo.

Ce n'est pas assez bon, et je suis à la recherche d'une solution plus rapide. Je me demandais si quelqu'un pourrait me dire à propos de meilleur en Java OU en appelant un script shell, la commande, quelle que soit hack vous le savez, il doit être plus rapide, tout le reste n'a pas d'importance ce moment.

26voto

Jörn Horstmann Points 18118

J'utilise un code similaire au suivant pour redimensionner les images, j'ai supprimé la partie relative à la préservation du rapport de format. La performance était nettement supérieure à 10 secondes par image, mais je ne me souviens pas de chiffres exacts. Pour archiver une meilleure qualité lors de la réduction de la taille, vous devez redimensionner l’image en plusieurs étapes si la taille de l’image originale est plus de deux fois supérieure à celle de la vignette souhaitée. Chaque étape doit redimensionner l’image précédente à environ la moitié de sa taille.

 public static BufferedImage getScaledImage(BufferedImage image, int width, int height) throws IOException {
    int imageWidth  = image.getWidth();
    int imageHeight = image.getHeight();

    double scaleX = (double)width/imageWidth;
    double scaleY = (double)height/imageHeight;
    AffineTransform scaleTransform = AffineTransform.getScaleInstance(scaleX, scaleY);
    AffineTransformOp bilinearScaleOp = new AffineTransformOp(scaleTransform, AffineTransformOp.TYPE_BILINEAR);

    return bilinearScaleOp.filter(
        image,
        new BufferedImage(width, height, image.getType()));
}
 

14voto

Klarth Points 1662

Avez-vous vraiment besoin de la qualité fournie par Image.SCALE_SMOOTH? Sinon, vous pouvez utiliser Image.SCALE_FAST . Vous pourriez trouver cet article utile si vous voulez vous en tenir à quelque chose fourni par Java.

13voto

johnstosh Points 51

Eh bien, Jacob et moi voulions redimensionner une image, pas une image Buffered. Donc nous avons fini avec ce code:

 /**
 * we want the x and o to be resized when the JFrame is resized
 *
 * @param originalImage an x or an o. Use cross or oh fields.
 *
 * @param biggerWidth
 * @param biggerHeight
 */
private Image resizeToBig(Image originalImage, int biggerWidth, int biggerHeight) {
    int type = BufferedImage.TYPE_INT_ARGB;


    BufferedImage resizedImage = new BufferedImage(biggerWidth, biggerHeight, type);
    Graphics2D g = resizedImage.createGraphics();

    g.setComposite(AlphaComposite.Src);
    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    g.drawImage(originalImage, 0, 0, biggerWidth, biggerHeight, this);
    g.dispose();


    return resizedImage;
}
 

11voto

dogbane Points 85749

Vous pouvez utiliser ImageMagick pour créer des vignettes .

 convert -define jpeg:size=500x180  hatching_orig.jpg  -auto-orient \
        -thumbnail 250x90   -unsharp 0x.5  thumbnail.gif
 

Pour l'utiliser depuis Java, vous pouvez essayer JMagick qui fournit une interface Java (JNI) à ImageMagick. Ou vous pouvez simplement appeler les commandes ImageMagick directement à l’aide de Runtime.exec ou ProcessBuilder .

3voto

echox Points 2227

Vous ne l'avez jamais fait un compromis entre la vitesse de la redimensionner et de la qualité de l'image résultante. Vous pourriez essayer une autre mise à l'échelle de l'algorithme du JDK.

La meilleure et la plus souple de l'outil de retouche d'image autant que je sache est ImageMagick.

Il y a deux interfaces pour le Langage Java:

  • JMagick - est une Interface JNI pour ImageMagick. Voir les projets Wiki pour obtenir plus d'informations.
  • im4java - est une interface de ligne de commande pour ImageMagick. Il n'est pas, comme JMagick, basée sur la JNI.

Vous devriez préférer im4java avant d'utiliser la ligne de commande directement à l'appel de ImageMagick.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X