33

テキストコンテンツを画像ファイルに変換できるJavaライブラリはありますか? 私はImageMagick (この場合は JMagick) しか知りませんが、外部バイナリをインストールしたくありません (私のアプリは Tomcat サーバーに .war ファイルとしてデプロイされるため、Java 以外の依存関係は必要ありません)。 .

たとえば、文字列「Hello」から、次の単純な画像を生成したいと思います。

文字列からの基本イメージ

4

6 に答える 6

75

Graphics 2D API は、必要なものを実現できる必要があります。複雑なテキスト処理機能もいくつか備えています。

ここに画像の説明を入力

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class TextToGraphics {

    public static void main(String[] args) {
        String text = "Hello";

        /*
           Because font metrics is based on a graphics context, we need to create
           a small, temporary image so we can ascertain the width and height
           of the final image
         */
        BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = img.createGraphics();
        Font font = new Font("Arial", Font.PLAIN, 48);
        g2d.setFont(font);
        FontMetrics fm = g2d.getFontMetrics();
        int width = fm.stringWidth(text);
        int height = fm.getHeight();
        g2d.dispose();

        img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        g2d = img.createGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
        g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
        g2d.setFont(font);
        fm = g2d.getFontMetrics();
        g2d.setColor(Color.BLACK);
        g2d.drawString(text, 0, fm.getAscent());
        g2d.dispose();
        try {
            ImageIO.write(img, "png", new File("Text.png"));
        } catch (IOException ex) {
            ex.printStackTrace();
        }

    }

}

書き込み/保存と画像もチェックしてください

警告これを使用して90kのPNG画像を生成しましたが、IEでは表示できますが、Chromeバージョン70.0.3538.77では表示できないことがわかりました

上記のコードは私にとっては問題なく機能します(テキストの色をに変更しWHITEて、クロムで表示できるようにしました)

Chrome での実行

Java 10.0.2 を使用する Mac OS Mojave 10.14 で Chrome 70.0.3538.77 を使用していました。結果の画像は4778x2411ピクセルでした...

更新しました...

IE では白地に黒ですが、Chrome では黒地に黒です。それでも、背景を白に設定しました。

あなたが私に言っているのは、ブラウザーが異なるデフォルトの背景を使用しているため、透明な PNG はブラウザーごとに異なって表示されるということです...なぜこれに驚いたのですか?

元のソリューションでは、意図的に透明ベースの画像を使用していました。BufferedImage.TYPE_INT_ARGBこれは、アルファ ( A) ベースRGBのカラー モデルを適用するイメージの作成時に を使用することで明らかです。

g2d.setBackground(Color.white) があるので、これは予想外です。

setBackgroundいいえ、実際には、実際に何が行われ、どのように使用されるべきかを理解していれば、完全に期待されています。

JavaDocsから

Graphics2D コンテキストの背景色を設定します。背景色は、領域をクリアするために使用されます。Component に対して Graphics2D が構築されると、背景色は Component から継承されます。Graphics2D コンテキストで背景色を設定すると、後続の clearRect 呼び出しにのみ影響し、Component の背景色には影響しません。コンポーネントの背景を変更するには、コンポーネントの適切なメソッドを使用します。

物事の「音」から、背景色が塗りつぶされた不透明な画像が必要です。繰り返しになりますが、JavaDocsに移ります。少し読むとBufferedImage.TYPE_INT_RGB、アルファ チャネルが削除される にたどり着きますが、それでも画像の背景を塗りつぶす必要があります。

このために、機能するという理由だけでGraphics2D#setColorandGraphics2D#fillRectを使用します。

したがって、上記の修正版は次のようになります...

img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
g2d = img.createGraphics();
//...
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, img.getWidth(), img.getHeight());
g2d.setColor(Color.BLACK);
g2d.drawString(text, 0, fm.getAscent());
g2d.dispose();
try {
    ImageIO.write(img, "png", new File("Text.png"));
} catch (IOException ex) {
    ex.printStackTrace();
}

「jpg」に変更すると、IE と Chrome の両方で黒の背景にオレンジ/ピンクのテキストが表示されます

ImageIOこれは、アルファ チャネルをサポートしていない透明カラー モデルのアルファ チャネルを JPG に適用しようとする、よく知られた、悲しいことに の一般的な問題/バグに関連しています。

詳細については、ImageIO.write jpg ファイルの使用に関する問題: ピンクの背景を参照してください。

ただし、基本的な解決策は、アルファ チャネルをサポートする PNG を使用するか、透明でない画像を使用することです。

だから、これはすべての長短です。問題は元の回答ではなく、AWT ライブラリ、Chrome、または IE でもありませんが、これらの API (および例) がどのように機能するかを理解していないことが原因ですImageIOBufferedImageGraphics

于 2013-09-14T10:36:06.477 に答える
8

外部ライブラリがない場合は、次のようにします。

  1. テキストのサイズをピクセル単位で測定します (「テキストの測定」を参照) 。
  2. テキストに適したサイズの java.awt.image.BufferedImage を作成します
  3. createGraphics() メソッドを使用して、BufferedImage のグラフィック オブジェクトを取得します。
  4. テキストを描く
  5. javax ImageIO クラスを使用して画像を保存します

編集 - リンクを修正

于 2013-09-14T10:32:56.943 に答える