Augmentation de la Résolution et Réduction de la Taille d'une Image en Java


Quand j'ai demandé cela pour la première fois, j'ai inclus autant d'informations que possible, car je ne sais jamais ce qui aidera quelqu'un s'il peut donner une solution à m, mais d'après les réponses, il semble que je n'ai pas clairement expliqué mon point de vue.

Je laisse le texte original en bas et raccourcit ceci. J'espère qu'il est clair.

Je travaille avec des images qui me sont retournées d'un autre programme. Je peux obtenir une image, par exemple, 8x10 à 72 DPI ou la même image à 16x20, également à 72DPI.

Je travaille en Java. Ce que je voudrais faire, c'est prendre l'image 16x20 et la redimensionner. Si possible, je voudrais simplement changer le fichier donc au lieu d'être 16x20 à 72DPI, c'est 8x10 à 144DPI.

Je sais que c'est toujours le même nombre de pixels, mais les téléspectateurs diront quelle est la taille d'une image et quel est le DPI et aussi certains ouvrent une image à sa taille réelle, donc je préfère qu'ils traitent le 16x20 comme une image plus petite avec une résolution plus élevée.

Puis-je faire cela en Java? Vais-je perdre toutes les données? Comment puis - je le faire-puis-je simplement changer les métadonnées dans le fichier png ou jpg?

-----(question originale ci-dessous ici) - - - - -

J'ai vu quelques questions qui se rapprochent de cela, mais c'est un peu différent.

Je sais que vous pouvez diminuer la résolution d'imageavec une image en Java ( aussi ici). Toutes les recherches que j'ai faites ont été concernées par la diminution de la résolution d'une image.

J'ai le problème inverse. Je travaille avec une image que je reviens en 72DPI. L'avantage est que je peux augmenter la taille de l'image, donc je pourrais faire la taille 100%, 200%, 400% et ainsi de suite. Toutes les images sont à 72DPI, donc si j'utilise 200% pour le zoom, puis ouvre l'image dans une visionneuse et lui donne la même taille que l'image 100%, je vois une meilleure résolution.

Pour plus de clarté - je reçois une image de quelqu'un d'autre, elle pourrait être générée à partir d'un PDF ou d'une image, mais je suis donné l'image d'un autre programme. Peu importe ce que je faites, cette image est à 72DPI. Je ne peux pas changer cela, mais je peux spécifier la taille à 200% et il revient toujours à 72DPI, juste deux fois plus grand et avec plus de détails.

Je ne suis pas un expert en graphisme et c'est la première fois que je fais une programmation qui utilise des graphiques. La sortie peut être jpg ou png, donc le format n'est pas si important. (Je pourrais aussi utiliser d'autres formats si nécessaire.)

Disons que l'image originale est une photo - 8" x 10", et à 72 DPI. Si je demande un zoom à 200%, je obtenez une image de 16" x 20" à 72DPI.

Puis-je, dans Java, changer cette image 16" x 20" 72DPI plus grande en une image 144DPI de 8" x 10" sans perdre de données? En d'autres termes, doubler le DPI, mais couper la taille en deux?

Et, surtout, puis-je le faire sans perdre de résolution? (Je pense que cela peut être fait.)

Author: Community, 2012-12-20

2 answers

Non, si vous prenez une image 8x10 72dpi et demandez un zoom 200%, vous obtiendrez un 16x20 à 36 dpi. Vous ne pouvez pas augmenter comme par magie la résolution de l'image.

Ce qui compte est le nombre total de pixels dans l'image. Le DPI indiqué est exactement ce que le DPI sera à une taille spécifique. Prenez votre image 8x10 à 72dpi. Il a 576x720 pixels. Si vous zoomez à 200%, vous avez toujours le même nombre de pixels, mais maintenant ils seront répartis sur deux fois les dimensions linéaires, ce qui signifie que les pixels individuels seront plus grand. Certains logiciels tenteront d'augmenter la résolution en interpolant les pixels, c'est-à-dire en créant de nouveaux pixels en faisant la moyenne des voisins les plus proches. Cela peut donner l'impression d'une plus haute résolution, mais l'image ne contient plus de données. Il a toujours pour effet d'adoucir l'image, en particulier les arêtes vives ou les lignes.

Si vous réduisez la taille d'une image sans rééchantillonnage, vous augmentez la résolution imprimée ou affichée, mais l'image devient plus petite. Pour l' même image, augmenter le DPI à 144 réduira la taille de l'image à 4x5.

 4
Author: Jim Garrison, 2012-12-20 18:04:45

C'est délicat car, comme beaucoup en Java, vous ne pouvez pas simplement accéder à quelque chose de manière simple. Java ne garde pas de trace du DPI, mais il utilise des points par millimètre. En outre, une autre partie qui prête à confusion est que vous ne pouvez pas modifier ce type d'informations dans une image ou dans une image tampon. Vous ne pouvez modifier ces informations que lorsque vous écrivez une sortie BufferedImage via un ImageWriter.

J'ai pu le faire. Comme je l'ai dit, je pouvais spécifier le zoom sur l'image qui était retournés pour moi. Quel que soit le niveau de zoom, la sortie était de 72 DPI. Mon objectif était de 300 DPI. J'ai spécifié un niveau de zoom de 400%. Donc, sur une image de 8" de large de 72 DPI, cela m'a renvoyé une image de 32" de 72 DPI. Tout ce que j'avais à faire était de spécifier un DPI de 288 (72 x 4) pour remplacer le 72 DPI par défaut auquel j'avais affaire, puis quand il a été écrit, l'image avait le même nombre de pixels, mais était considérée comme étant faite à 288 DPI plutôt qu'à 72 DPI.

Voici un extrait de code:

//Supposé il y a déjà un ImageWriter iw

ImageWriteParam writeParam = writer.getDefaultWriteParam();
ImageTypeSpecifier typeSpecifier =
       ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
IIOMetadata metadata = writer.getDefaultImageMetadata(typeSpecifier, writeParam);
if (metadata.isReadOnly() || !metadata.isStandardMetadataFormatSupported()) {
    continue;
}

// Définir les paramètres et les informations

int DPI = 72 * scaling/100;
double dotsPerMilli = 1.0 * DPI / 10 / 2.54;
double checkDots = 1.0 * 144 / 10 / 2.54;
System.out.println("Dots per inch: " + DPI + ", DotsPerMilli: " + dotsPerMilli + ",
    CheckDots = " + checkDots);
IIOMetadataNode root = new IIOMetadataNode("javax_imageio_1.0");
IIOMetadataNode horiz = new IIOMetadataNode("HorizontalPixelSize");
horiz.setAttribute("value", Double.toString(dotsPerMilli));
IIOMetadataNode vert = new IIOMetadataNode("VerticalPixelSize");
vert.setAttribute("value", Double.toString(dotsPerMilli));
IIOMetadataNode dim = new IIOMetadataNode("Dimension");
dim.appendChild(horiz);
dim.appendChild(vert);
root.appendChild(dim);
metadata.mergeTree("javax_imageio_1.0", root);

/ / À partir d'ici, écrivez simplement un fichier en utilisant un ImageOutputStream

final ImageOutputStream stream = ImageIO.createImageOutputStream(outFile);
System.out.println("Output file: " + outFile);
try {
    writer.setOutput(ImageIO.createImageOutputStream(outFile));
    writer.write(metadata, new IIOImage(image_to_save, null, metadata),
    writeParam);
} catch (Exception e) {
    System.out.println("Caught exception " + e + " when trying to write out
        file.");
    System.exit(0);
} finally {
    stream.close();
}
 1
Author: Tango, 2012-12-27 07:11:33