Ajout de texte à une image en Java

1. Vue d'ensemble

Parfois, nous devons ajouter du texte à une image ou à un ensemble d'images. Faire cela manuellement est facile à l'aide d'un outil d'édition d'image. Mais lorsque nous voulons ajouter le même texte de la même manière à un nombre important d'images, il serait très utile de le faire par programmation.

Dans ce tutoriel rapide, nous allons apprendre à ajouter du texte aux images à l' aide de Java.

2. Ajout de texte à une image

Pour lire une image et ajouter du texte, nous pouvons utiliser différentes classes. Dans les sections suivantes, nous allons voir quelques options.

2.1. ImagePlus et ImageProcessor

Voyons d' abord comment utiliser les classes ImagePlus et ImageProcessor disponibles dans la bibliothèque ImageJ. Pour utiliser cette bibliothèque, nous devons inclure cette dépendance dans notre projet:

 net.imagej ij 1.51h 

Pour lire l'image, nous utiliserons la méthode statique openImage . Le résultat de cette méthode sera stocké en mémoire à l'aide d'un objet ImagePlus :

ImagePlus image = IJ.openImage(path);

Une fois l'image chargée en mémoire, ajoutons-y du texte en utilisant la classe ImageProcessor :

Font font = new Font("Arial", Font.BOLD, 18); ImageProcessor ip = image.getProcessor(); ip.setColor(Color.GREEN); ip.setFont(font); ip.drawString(text, 0, 20);

Avec ce code, ce que nous faisons, c'est ajouter le texte spécifié en vert en haut à gauche de l'image. Notez que nous définissons la position en utilisant les deuxième et troisième arguments de la méthode drawString qui représentent respectivement le nombre de pixels à partir de la gauche et du haut.

2.2. BufferedImage et graphiques

Ensuite, nous allons voir comment nous pouvons obtenir le même résultat en utilisant les classes BufferedImage et Graphics . La version standard de Java inclut ces classes, il n'y a donc pas besoin de bibliothèques supplémentaires.

De la même manière que nous avons utilisé openImage de ImageJ , nous allons utiliser la méthode de lecture disponible dans ImageIO :

BufferedImage image = ImageIO.read(new File(path));

Une fois l'image chargée en mémoire, ajoutons-y du texte en utilisant la classe Graphics :

Font font = new Font("Arial", Font.BOLD, 18); Graphics g = image.getGraphics(); g.setFont(font); g.setColor(Color.GREEN); g.drawString(text, 0, 20);

Comme nous pouvons le voir, les deux alternatives sont très similaires dans la manière dont elles sont utilisées. Dans ce cas, les deuxième et troisième arguments de la méthode drawString sont spécifiés de la même manière que nous l'avons fait pour la méthode ImageProcessor .

2.3. Dessiner en fonction de AttributedCharacterIterator

La méthode drawString disponible dans Graphics nous permet d' imprimer le texte à l'aide d'un AttributedCharacterIterator . Cela signifie qu'au lieu d'utiliser une chaîne simple , nous pourrions utiliser du texte avec certaines propriétés associées. Voyons un exemple:

Font font = new Font("Arial", Font.BOLD, 18); AttributedString attributedText = new AttributedString(text); attributedText.addAttribute(TextAttribute.FONT, font); attributedText.addAttribute(TextAttribute.FOREGROUND, Color.GREEN); Graphics g = image.getGraphics(); g.drawString(attributedText.getIterator(), 0, 20);

Cette façon d'imprimer le texte nous donne la possibilité d'associer le format directement à la chaîne , ce qui est plus propre que de changer les propriétés de l'objet Graphics chaque fois que nous voulons changer le format.

3. Alignement du texte

Maintenant que nous avons appris à ajouter un texte simple en haut à gauche d'une image, voyons maintenant comment nous pouvons ajouter ce texte à certaines positions .

3.1. Texte centré

Le premier type d'alignement que nous allons aborder est le centrage du texte . Pour définir dynamiquement la position correcte où nous voulons écrire le texte, nous devons trouver quelques informations:

  • Taille de l'image
  • Taille de police

Ces informations peuvent être obtenues très facilement. Dans le cas de la taille de l'image, ces données sont accessibles via les méthodes getWidth et getHeight de l' objet BufferedImage . D'autre part, pour obtenir les données relatives à la taille de la police, nous devons utiliser l'objet FontMetrics .

Voyons un exemple où nous calculons la position correcte de notre texte et le dessinons:

Graphics g = image.getGraphics(); FontMetrics metrics = g.getFontMetrics(font); int positionX = (image.getWidth() - metrics.stringWidth(text)) / 2; int positionY = (image.getHeight() - metrics.getHeight()) / 2 + metrics.getAscent(); g.drawString(attributedText.getIterator(), positionX, positionY);

3.2. Texte aligné en bas à droite

Le prochain type d'alignement que nous allons voir est en bas à droite . Dans ce cas, nous devons obtenir dynamiquement les positions correctes:

int positionX = (image.getWidth() - metrics.stringWidth(text)); int positionY = (image.getHeight() - metrics.getHeight()) + metrics.getAscent();

3.3. Texte situé en haut à gauche

Enfin, voyons comment imprimer notre texte en haut à gauche :

int positionX = 0; int positionY = metrics.getAscent();

Le reste des alignements peut être déduit des trois que nous avons vus.

4. Adaptation de la taille du texte en fonction de l'image

Lorsque nous dessinons le texte dans l'image, nous pouvons constater que ce texte dépasse la taille de l'image. Pour résoudre ce problème, nous devons adapter la taille de la police que nous utilisons en fonction de la taille de l'image.

Tout d'abord, nous devons obtenir la largeur et la hauteur attendues du texte en utilisant la police de base. Pour ce faire, nous utiliserons les classes FontMetrics , GlyphVector et Shape .

FontMetrics ruler = graphics.getFontMetrics(baseFont); GlyphVector vector = baseFont.createGlyphVector(ruler.getFontRenderContext(), text); Shape outline = vector.getOutline(0, 0); double expectedWidth = outline.getBounds().getWidth(); double expectedHeight = outline.getBounds().getHeight(); 

L'étape suivante consiste à vérifier si le redimensionnement de la police est nécessaire. Pour cela, comparons la taille attendue du texte et la taille de l'image:

boolean textFits = image.getWidth() >= expectedWidth && image.getHeight() >= expectedHeight;

Enfin, si notre texte ne rentre pas dans l'image, nous devons réduire la taille de la police. Nous utiliserons la méthode deriveFont pour cela:

double widthBasedFontSize = (baseFont.getSize2D()*image.getWidth())/expectedWidth; double heightBasedFontSize = (baseFont.getSize2D()*image.getHeight())/expectedHeight; double newFontSize = widthBasedFontSize < heightBasedFontSize ? widthBasedFontSize : heightBasedFontSize; newFont = baseFont.deriveFont(baseFont.getStyle(), (float)newFontSize);

Notez que nous devons obtenir la nouvelle taille de police en fonction de la largeur et de la hauteur et appliquer la plus petite d'entre elles.

5. Résumé

Dans cet article, nous avons vu comment écrire du texte dans une image en utilisant différentes méthodes.

Nous avons également appris comment obtenir dynamiquement la position où nous voulons imprimer notre texte en fonction de la taille de l'image et des propriétés de la police.

Enfin, nous avons vu comment adapter la taille de la police du texte au cas où elle dépasserait la taille de l'image où nous le dessinons.

Comme toujours, le code source complet de l'article est disponible à l'adresse over sur GitHub.