web-dev-qa-db-fra.com

Comment convertir une image tamponnée en image et vice-versa?

En fait, je travaille sur un logiciel d'édition d'image et maintenant je veux convertir l'image tamponnée, c'est-à-dire:

  BufferedImage buffer = ImageIO.read(new File(file));

à l'image c'est-à-dire dans le format quelque chose comme:

  Image image  = ImageIO.read(new File(file));

Est-il possible de le faire ?? Si oui, alors comment?

21
Arizvi

BufferedImage is a (n) Image, donc le transtypage implicite que vous faites dans la deuxième ligne peut être compilé directement. Si vous saviez qu'une image était vraiment une image tamponnée, vous devriez la diffuser explicitement comme ceci:

Image image = ImageIO.read(new File(file));
BufferedImage buffered = (BufferedImage) image;

Parce que BufferedImage étend l'image, il peut tenir dans un conteneur d'image. Cependant, n'importe quelle image peut y tenir, y compris celles qui ne sont pas un BufferedImage, et en tant que tel, vous pouvez obtenir une ClassCastException au moment de l'exécution si le type ne correspond pas, car un BufferedImage ne peut contenir aucun autre type à moins qu'il n'étende BufferedImage.

25
MetroidFan2002

Exemple: supposons que vous ayez une "image" que vous souhaitez mettre à l'échelle, vous aurez probablement besoin d'une image tamponnée, et vous commencerez probablement avec juste un objet "Image". Donc ça marche je pense ... L'AVATAR_SIZE est la largeur cible que nous voulons que notre image soit:

Image imgData = image.getScaledInstance(Constants.AVATAR_SIZE, -1, Image.SCALE_SMOOTH);     

BufferedImage bufferedImage = new BufferedImage(imgData.getWidth(null), imgData.getHeight(null), BufferedImage.TYPE_INT_RGB);

bufferedImage.getGraphics().drawImage(imgData, 0, 0, null);
11
user2080225

BufferedImage est une sous-classe de Image . Vous n'avez pas besoin de faire de conversion.

8
Matthew Farwell

La bonne façon est d'utiliser SwingFXUtils.toFXImage(bufferedImage,null) pour convertir un BufferedImage en une instance d'image JavaFX et SwingFXUtils.fromFXImage(image,null) pour l'opération inverse.

Facultativement, le deuxième paramètre peut être une WritableImage pour éviter une autre allocation d'objet.

Vous pouvez essayer enregistrer (ou écrire) l'image tamponnée avec les modifications que vous avez apportées, puis l'ouvrir en tant qu'image.

MODIFIER:

try {
    // Retrieve Image
    BufferedImage buffer = ImageIO.read(new File("old.png"));;
    // Here you can rotate your image as you want (making your magic)
    File outputfile = new File("saved.png");
    ImageIO.write(buffer, "png", outputfile); // Write the Buffered Image into an output file
    Image image  = ImageIO.read(new File("saved.png")); // Opening again as an Image
} catch (IOException e) {
    ...
}
6
Jose Garrido

Juste une information: rappelons-nous tous que la classe Image est en fait une classe abstraite et référencer une variable de celle-ci avec une BufferedImage ne stocke ou ne renvoie que l'adresse mémoire de tout objet.

Par conséquent, la méthode read() de la fonction statique Java.awt.image.imageIO _ Renvoie également un objet BufferedImage, donc il ne fait aucun doute que l'utilisation de l'opérateur/expression instanceof BufferedImage Sur cet objet retournera true.

En fait, étant abstraite, la classe Image a des signatures de méthode telles que:

  1. public abstract Graphics getGraphics()
  2. public abstract ImageProducer getSource()

entre autres.

Je souligne, une variable Image réelle ne contient que l'adresse mémoire d'un objet concret de sous-classe Image, presque comme des pointeurs en C, C++, Ada, etc.

Si vous êtes introduit ou avancé dans ces langages, et aussi de Java instances d'interface comme Runnable, javax.sound.Clip, AWT Shape, etc. ... Notez que Image a: public abstract Image getScaledInstance(...) - vous obtenez le point. (Bien sûr, la mise à l'échelle dans la programmation graphique 2D est interchangeable avec le redimensionnement, pour lequel la précision est souhaitable).

Mais dans un cas impossible où ici la méthode ImageIO retourne ! (instanceof BufferedImage) il suffit de créer un nouvel objet BufferedImage avec cet ImgObjNotInstncfBufImg apassé à l'un de ses arguments constructeurs. Ensuite, at (rational) manipulera cela dans la logique de votre code.

Quoi qu'il en soit, la classe Affine Transform est appropriée pour transformer des formes et des images en des formulaires à l'échelle, tournés, déplacés, etc., donc je vous recommande d'étudier l'utilisation d'une "transformation affine".

Prenez note que vous pouvez manipuler les pixels réels dans une telle image - bien un autre jargon graphique 2D technique qui doit être référencé à partir d'un glossaire technique - qui peut-être une compétence excercisée dans Java façons d'opérations binaires dans le sens des aiguilles d'une montre) sera nécessaire, dans les types de tampons d'image qui stockent les attributs de couleur individuels dans un format compact de 32 octets - 7 bits chacun pour les valeurs alpha et RVB.

Je suppose que tu vas l'utiliser pour superposer des images. Donc, ENFIN, le rationnel est que vous ne faites référence qu'à BufferedImage avec l'image abstraite, et si jamais votre objet Image n'est pas encore un BufferedImage, alors vous pouvez simplement créer une image à partir de cette instance d'image liée mais non-tamponnée sans avoir à vous soucier de conversion, de casting, d'autoboxing ou autre; manipuler une BufferedImage signifie vraiment manipuler également l'objet racine de données Image sous-jacent vers lequel il pointe.

D'accord, fini; Je pense que j'ai certainement extrait et éclaté le blocage auquel vous pensiez être confronté. Comme je l'ai dit, les classes abstraites en Java, ainsi que les interfaces, sont à peu près l'équivalent des opérateurs de bas niveau, plus proches du matériel, appelés pointeurs dans d'autres langages.

4
Verse Villalon Gamboa