Java에서 이미지에 텍스트 추가

1. 개요

때로는 이미지 나 이미지 세트에 텍스트를 추가해야합니다. 이미지 편집 도구를 사용하면이 작업을 수동으로 쉽게 수행 할 수 있습니다. 그러나 동일한 텍스트를 동일한 방식으로 상당수의 그림에 추가하려는 경우이를 프로그래밍 방식으로 수행하는 것이 매우 유용합니다.

이 빠른 자습서에서는 Java를 사용하여 이미지에 텍스트를 추가하는 방법을 알아 봅니다 .

2. 이미지에 텍스트 추가

이미지를 읽고 텍스트를 추가하려면 다른 클래스를 사용할 수 있습니다. 다음 섹션에서는 몇 가지 옵션을 살펴 보겠습니다.

2.1. ImagePlusImageProcessor

먼저 ImageJ 라이브러리에서 사용할 수있는 ImagePlusImageProcessor 클래스를 사용하는 방법을 살펴 보겠습니다 . 이 라이브러리를 사용하려면 프로젝트에이 종속성을 포함해야합니다.

 net.imagej ij 1.51h 

이미지를 읽기 위해 openImage 정적 메서드를 사용합니다 . 이 메서드의 결과는 ImagePlus 개체를 사용하여 메모리에 저장됩니다 .

ImagePlus image = IJ.openImage(path);

이미지를 메모리에로드했으면 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);

이 코드를 사용하여 이미지 왼쪽 상단에 지정된 텍스트를 녹색으로 추가합니다. 왼쪽과 위쪽에서 각각 픽셀 수를 나타내는 drawString 메서드 의 두 번째 및 세 번째 인수를 사용하여 위치를 설정합니다 .

2.2. BufferedImage그래픽

다음으로 BufferedImageGraphics 클래스를 사용하여 동일한 결과를 얻는 방법 을 살펴 보겠습니다 . Java의 표준 빌드에는 이러한 클래스가 포함되어 있으므로 추가 라이브러리가 필요하지 않습니다.

ImageJ의 openImage 를 사용한 것과 같은 방식 으로 ImageIO 에서 사용할 수 있는 read 메서드를 사용할 것입니다 .

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

이미지를 메모리에로드했으면 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);

보시다시피 두 가지 대안은 사용 방식이 매우 유사합니다. 이 경우 drawString 메서드의 두 번째 및 세 번째 인수 는 ImageProcessor 메서드에 대해 수행 한 것과 동일한 방식으로 지정됩니다 .

2.3. AttributedCharacterIterator 기반 그리기

Graphics 에서 사용할 수있는 drawString 메서드를 사용하면 AttributedCharacterIterator를 사용하여 텍스트인쇄 할 수 있습니다 . 즉, 일반 String 을 사용하는 대신 일부 속성이 연결된 텍스트를 사용할 수 있습니다. 예를 보겠습니다.

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);

텍스트를 인쇄하는이 방법은 형식을 String 과 직접 연결할 수있는 기회를 제공 합니다. 이는 형식을 변경할 때마다 Graphics 객체 속성을 변경하는 것보다 더 깔끔 합니다.

3. 텍스트 정렬

이미지의 왼쪽 상단에 간단한 텍스트를 추가하는 방법을 배웠으므로 이제이 텍스트를 특정 위치에 추가하는 방법을 살펴 보겠습니다 .

3.1. 중앙 텍스트

우리가 다룰 첫 번째 유형의 정렬 은 텍스트를 가운데 에 맞추는 것 입니다. 텍스트를 작성할 올바른 위치를 동적으로 설정하려면 몇 가지 정보를 알아 내야합니다.

  • 이미지 크기
  • 글꼴 크기

This information can be obtained very easily. In the case of the image size, this data can be accessed through the methods getWidth and getHeight of the BufferedImage object. On the other hand, to get the data related to the font size we need to use the object FontMetrics.

Let's see an example where we calculate the correct position for our text and draw it:

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. Text Aligned in the Bottom Right

The next type of alignment that we're going to see is the bottom right. In this case, we need to dynamically get the correct positions:

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

3.3. Text Located in the Top Left

Finally, let's see how to print our text in the top left:

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

The rest of the alignments can be deduced from the three we've seen.

4. Adapting Text Size Based on Image

When we draw the text in the image, we might find that this text exceeds the size of the image. To solve this, we have to adapt the size of the font that we're using based on the image size.

First, we need to obtain the expected width and height of the text using the base font. In order to achieve this, we'll make use of the classes FontMetrics, GlyphVector, and 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(); 

The next step is to check if the resize of the font is necessary. For this purpose, let's compare the expected size of the text and the size of the image:

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

Finally, if our text doesn't fit in the image, we have to reduce the font size. We'll use the method deriveFont for that:

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);

너비와 높이를 기준으로 새 글꼴 크기를 구하고 가장 낮은 글꼴을 적용해야합니다.

5. 요약

이 기사에서는 다양한 방법을 사용하여 이미지에 텍스트를 작성하는 방법을 살펴 보았습니다.

또한 이미지 크기와 글꼴 속성을 기반으로 텍스트를 인쇄 할 위치를 동적으로 가져 오는 방법도 배웠습니다.

마침내 우리는 텍스트를 그리는 이미지의 크기를 초과하는 경우 텍스트의 글꼴 크기를 조정하는 방법을 보았습니다.

항상 그렇듯이 기사의 전체 소스 코드는 GitHub에서 사용할 수 있습니다.