Tekst toevoegen aan een afbeelding in Java

1. Overzicht

Soms moeten we wat tekst toevoegen aan een afbeelding of een reeks afbeeldingen. Dit handmatig doen is eenvoudig met behulp van een beeldbewerkingstool. Maar als we dezelfde tekst op dezelfde manier aan een aanzienlijk aantal afbeeldingen willen toevoegen, zou het erg handig zijn om dit programmatisch te doen.

In deze korte tutorial gaan we leren hoe u tekst aan afbeeldingen toevoegt met behulp van Java.

2. Tekst aan een afbeelding toevoegen

Om een ​​afbeelding te lezen en wat tekst toe te voegen, kunnen we verschillende klassen gebruiken. In de volgende secties zullen we een aantal opties zien.

2.1. ImagePlus en ImageProcessor

Laten we eerst eens kijken hoe de lessen te gebruiken ImagePlus en ImageProcessor die beschikbaar zijn in de ImageJ-bibliotheek. Om deze bibliotheek te gebruiken, moeten we deze afhankelijkheid in ons project opnemen:

 net.imagej ij 1.51h 

Om de afbeelding te lezen gebruiken we de openImage statische methode. Het resultaat van deze methode wordt in het geheugen opgeslagen met een ImagePlus voorwerp:

ImagePlus afbeelding = IJ.openImage (pad);

Zodra we de afbeelding in het geheugen hebben geladen, kunnen we er wat tekst aan toevoegen met behulp van de klasse ImageProcessor:

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

Met deze code voegen we de opgegeven tekst in het groen toe linksboven in de afbeelding. Merk op dat we de positie instellen met behulp van de tweede en derde argumenten van de drawString methode die het aantal pixels van respectievelijk links en boven vertegenwoordigen.

2.2. BufferedImage en Grafische afbeeldingen

Vervolgens gaan we zien hoe we hetzelfde resultaat kunnen bereiken met behulp van de klassen BufferedImage en Grafische afbeeldingen. De standaard build van Java bevat deze klassen, dus er zijn geen extra bibliotheken nodig.

Op dezelfde manier als we gebruikten openImage van ImageJ, gaan we de lezen methode beschikbaar in ImageIO:

BufferedImage afbeelding = ImageIO.read (nieuw bestand (pad));

Zodra we de afbeelding in het geheugen hebben geladen, kunnen we er wat tekst aan toevoegen met behulp van de klasse Grafische afbeeldingen:

Lettertype font = nieuw lettertype ("Arial", Font.BOLD, 18); Afbeeldingen g = image.getGraphics (); g.setFont (lettertype); g.setColor (Color.GREEN); g.drawString (tekst, 0, 20);

Zoals we kunnen zien, lijken beide alternatieven sterk op de manier waarop ze worden gebruikt. In dit geval het tweede en derde argument van de methode drawString worden gespecificeerd op dezelfde manier als we hebben gedaan voor de ImageProcessor methode.

2.3. Teken op basis van AttributedCharacterIterator

De methode drawString beschikbaar in Grafische afbeeldingen sta ons toe om print de tekst met een AttributedCharacterIterator. Dit betekent dat in plaats van een gewoon Draad, kunnen we tekst gebruiken met een aantal bijbehorende eigenschappen. Laten we een voorbeeld bekijken:

Font font = nieuw font ("Arial", Font.BOLD, 18); AttributedString attributedText = nieuwe AttributedString (tekst); attributedText.addAttribute (TextAttribute.FONT, lettertype); attributedText.addAttribute (TextAttribute.FOREGROUND, Color.GREEN); Afbeeldingen g = image.getGraphics (); g.drawString (attributedText.getIterator (), 0, 20);

Deze manier van afdrukken van de tekst geeft ons de kans om het formaat rechtstreeks te associëren met de Draad, wat schoner is dan veranderen Grafische afbeeldingen objecteigenschappen wanneer we het formaat willen wijzigen.

3. Tekstuitlijning

Nu we hebben geleerd hoe we een eenvoudige tekst linksboven in een afbeelding kunnen toevoegen, gaan we kijken hoe we dit kunnen toevoegen tekst op bepaalde posities.

3.1. Gecentreerde tekst

Het eerste type uitlijning dat we gaan aanpakken is centreren van de tekst. Om dynamisch de juiste positie in te stellen waar we de tekst willen schrijven, hebben we wat informatie nodig:

  • Afbeeldingsgrootte
  • Lettertypegrootte

Deze informatie kan heel gemakkelijk worden verkregen. In het geval van de afbeeldingsgrootte zijn deze gegevens toegankelijk via de methoden getWidth en getHeight van de BufferedImage voorwerp. Aan de andere kant, om de gegevens met betrekking tot de lettergrootte te krijgen, moeten we het object gebruiken FontMetrics.

Laten we een voorbeeld bekijken waarin we de juiste positie voor onze tekst berekenen en deze tekenen:

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

3.2. Tekst rechtsonder uitgelijnd

Het volgende type uitlijning dat we gaan zien, is rechtsonder. In dit geval moeten we dynamisch de juiste posities krijgen:

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

3.3. Tekst bevindt zich in de linkerbovenhoek

Laten we eindelijk eens kijken hoe u onze tekst kunt afdrukken in de linkerbovenhoek:

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

De rest van de uitlijningen kan worden afgeleid uit de drie die we hebben gezien.

4. Tekstgrootte aanpassen op basis van afbeelding

Wanneer we de tekst in de afbeelding tekenen, kunnen we ontdekken dat deze tekst groter is dan de afbeelding. Om dit op te lossen, moeten we pas de grootte van het lettertype aan die we gebruiken op basis van de afbeeldingsgrootte.

Eerst moeten we de verwachte breedte en hoogte van de tekst verkrijgen met behulp van het basislettertype. Om dit te bereiken maken we gebruik van de lessen FontMetrics, GlyphVector, en Vorm.

FontMetrics-liniaal = graphics.getFontMetrics (baseFont); GlyphVector-vector = baseFont.createGlyphVector (ruler.getFontRenderContext (), tekst); Vormoverzicht = vector.getOutline (0, 0); dubbele verwachteWidth = outline.getBounds (). getWidth (); dubbele verwachteHeight = outline.getBounds (). getHeight (); 

De volgende stap is om te controleren of het formaat van het lettertype moet worden aangepast. Laten we voor dit doel de verwachte grootte van de tekst en de grootte van de afbeelding vergelijken:

boolean textFits = image.getWidth ()> = verwachteWidth && image.getHeight ()> = verwachteHoogte;

Ten slotte, als onze tekst niet in de afbeelding past, moeten we de lettergrootte verkleinen. We zullen de methode gebruiken afleidenLettertype daarom:

dubbele breedteBasedFontSize = (baseFont.getSize2D () * image.getWidth ()) / verwachteWidth; dubbele hoogteBasedFontSize = (baseFont.getSize2D () * image.getHeight ()) / verwachtHeight; double newFontSize = widthBasedFontSize <heightBasedFontSize? widthBasedFontSize: hoogteBasedFontSize; newFont = baseFont.deriveFont (baseFont.getStyle (), (float) newFontSize);

Merk op dat we de nieuwe lettergrootte moeten verkrijgen op basis van zowel breedte als hoogte en de laagste moeten toepassen.

5. Samenvatting

In dit artikel hebben we gezien hoe je op verschillende manieren tekst in een afbeelding kunt schrijven.

We hebben ook geleerd hoe we dynamisch de positie kunnen krijgen waar we onze tekst willen afdrukken op basis van de afbeeldingsgrootte en de lettertype-eigenschappen.

Eindelijk hebben we gezien hoe we de lettergrootte van de tekst kunnen aanpassen voor het geval deze groter is dan de afbeelding waarin we deze tekenen.

Zoals altijd is de volledige broncode van het artikel beschikbaar op GitHub.