java text emojis为图像添加表情符号

时间:2015-02-12 09:16:55

标签: java text utf-8 character-encoding emoji

我有一种绘制图像的方法,其中文本包含在该图像中。现在,文本包含exo的表情符号,并且它不会像在图像中那样被打印,而是像这样[]的矩形框。 我用过java.text。和java.awt。这个课程

private void drawMessageString(Graphics2D g, final int messageHeight) {
        int x = CRUSH_PADDING + CRUSH_MESSAGE_LR_PADDING;
        int y = CRUSH_PADDING + TOP_BAR_HEIGHT + CRUSH_MESSAGE_TB_PADDING;

            String myString="he new guy from New Zealand who is playing tennis   ";


            try {
                byte ptext[] = myString.getBytes("UTF-8");
                    String value;
                value = new String(ptext, "UTF-8");
                TextRenderer.drawString(g, value, FontUtils.getInstance().getFont(FONT_PROXIMA_NOVA, 24.0f), MSG_COLOR, new Rectangle(x, y, CRUSH_MESSAGE_WIDTH, messageHeight), TextAlignment.TOP, TextFormat.FIRST_LINE_VISIBLE);

            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    }

TextRenderer只是一个创建的类,它将代码包含在drawString和rectangle中。

应该解决这个问题?

TextRenderer.java ==>

package com.text;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.awt.geom.Rectangle2D;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;

/**
 * A class which provides static methods for rendering text using alignment.
 *
 * @author  Chris Copeland
 * @version 1.0
 */
public final class TextRenderer {

    /**
     * Initialize a new instance of the {@link TextRenderer} class.
     */
    private TextRenderer() {

    }

    /**
     * Draws a string onto a <code>Graphics</code> handle, using a
     * <code>Font</code>, <code>Color</code> and target bounds to calculate the
     * location and automatic wrapping of text. The <i>align</i> property
     * determines where the text will be positioned.
     *
     * @param g A <code>Graphics</code> handle which is the target of the draw
     * operation
     * @param text  A <code>String</code> containing the text to draw
     * @param font  The <code>Font</code> to use when drawing the text
     * @param color The <code>Color</code> to use when drawing the text
     * @param bounds    A <code>Rectangle</code> representing the bounds of the
     * text
     * @return  A <code>Rectangle</code> representing the bounds consumed by the
     * text
     */
    public static Rectangle drawString(Graphics g, String text, Font font, Color color, Rectangle bounds) {
        return drawString(g, text, font, color, bounds, TextAlignment.TOP_LEFT, TextFormat.NONE);
    }

    /**
     * Draws a string onto a <code>Graphics</code> handle, using a
     * <code>Font</code>, <code>Color</code> and target bounds to calculate the
     * location and automatic wrapping of text. The <i>align</i> property
     * determines where the text will be positioned.
     *
     * @param g A <code>Graphics</code> handle which is the target of the draw
     * operation
     * @param text  A <code>String</code> containing the text to draw
     * @param font  The <code>Font</code> to use when drawing the text
     * @param color The <code>Color</code> to use when drawing the text
     * @param bounds    A <code>Rectangle</code> representing the bounds of the
     * text
     * @param align A <code>TextAlignment</code> value representing the location
     * to draw the text, relative to the <i>bounds</i>
     * @return  A <code>Rectangle</code> representing the bounds consumed by the
     * text
     */
    public static Rectangle drawString(Graphics g, String text, Font font, Color color, Rectangle bounds, TextAlignment align) {
        return drawString(g, text, font, color, bounds, align, TextFormat.NONE);
    }

    /**
     * Draws a string onto a <code>Graphics</code> handle, using a
     * <code>Font</code>, <code>Color</code> and target bounds to calculate the
     * location and automatic wrapping of text. The <i>align</i> property
     * determines where the text will be positioned.
     *
     * @param g A <code>Graphics</code> handle which is the target of the draw
     * operation
     * @param text  A <code>String</code> containing the text to draw
     * @param font  The <code>Font</code> to use when drawing the text
     * @param color The <code>Color</code> to use when drawing the text
     * @param bounds    A <code>Rectangle</code> representing the bounds of the
     * text
     * @param align A <code>TextAlignment</code> value representing the location
     * to draw the text, relative to the <i>bounds</i>
     * @param format    Additional formatting flags to use when drawing (see
     * <code>TextFormat</code> class)
     * @return  A <code>Rectangle</code> representing the bounds consumed by the
     * text
     */
    public static Rectangle drawString(Graphics g, String text, Font font, Color color, Rectangle bounds, TextAlignment align, int format) {
        if (g == null) {
            throw new NullPointerException("The graphics handle cannot be null.");
        }
        if (text == null) {
            throw new NullPointerException("The text cannot be null.");
        }
        if (font == null) {
            throw new NullPointerException("The font cannot be null.");
        }
        if (color == null) {
            throw new NullPointerException("The text color cannot be null.");
        }
        if (bounds == null) {
            throw new NullPointerException("The text bounds cannot be null.");
        }
        if (align == null) {
            throw new NullPointerException("The text alignment cannot be null.");
        }
        if (text.length() == 0) {
            return new Rectangle(bounds.x, bounds.y, 0, 0);
        }

        Graphics2D g2D = (Graphics2D) g;

        AttributedString attributedString = new AttributedString(text);
        attributedString.addAttribute(TextAttribute.FOREGROUND, color);
        attributedString.addAttribute(TextAttribute.FONT, font);

        AttributedCharacterIterator attributedCharIterator = attributedString.getIterator();

        FontRenderContext fontContext = new FontRenderContext(null, !TextFormat.isEnabled(format, TextFormat.NO_ANTI_ALIASING), false);
        LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(attributedCharIterator, fontContext);

        Point targetLocation = new Point(bounds.x, bounds.y);
        int nextOffset = 0;

        if (align.isMiddle() || align.isBottom()) {
            if (align.isMiddle()) {
                targetLocation.y = bounds.y + (bounds.height / 2);
            }
            if (align.isBottom()) {
                targetLocation.y = bounds.y + bounds.height;
            }

            while (lineMeasurer.getPosition() < text.length()) {
                nextOffset = lineMeasurer.nextOffset(bounds.width);
                nextOffset = nextTextIndex(nextOffset, lineMeasurer.getPosition(), text);

                TextLayout textLayout = lineMeasurer.nextLayout(bounds.width, nextOffset, false);

                if (align.isMiddle()) {
                    targetLocation.y -= (textLayout.getAscent() + textLayout.getLeading() + textLayout.getDescent()) / 2;
                }
                if (align.isBottom()) {
                    targetLocation.y -= (textLayout.getAscent() + textLayout.getLeading() + textLayout.getDescent());
                }
            }

            if (TextFormat.isEnabled(format, TextFormat.FIRST_LINE_VISIBLE)) {
                targetLocation.y = Math.max(0, targetLocation.y);
            }

            lineMeasurer.setPosition(0);
        }

        if (align.isRight() || align.isCenter()) {
            targetLocation.x = bounds.x + bounds.width;
        }

        Rectangle consumedBounds = new Rectangle(targetLocation.x, targetLocation.y, 0, 0);

        while (lineMeasurer.getPosition() < text.length()) {
            nextOffset = lineMeasurer.nextOffset(bounds.width);
            nextOffset = nextTextIndex(nextOffset, lineMeasurer.getPosition(), text);

            TextLayout textLayout = lineMeasurer.nextLayout(bounds.width, nextOffset, false);
            Rectangle2D textBounds = textLayout.getBounds();

            targetLocation.y += textLayout.getAscent();
            consumedBounds.width = Math.max(consumedBounds.width, (int) textBounds.getWidth());

            switch (align) {
                case TOP_LEFT:
                case MIDDLE_LEFT:
                case BOTTOM_LEFT:
                    textLayout.draw(g2D, targetLocation.x, targetLocation.y);
                    break;

                case TOP:
                case MIDDLE:
                case BOTTOM:
                    targetLocation.x = bounds.x + (bounds.width / 2) - (int) (textBounds.getWidth() / 2);
                    consumedBounds.x = Math.min(consumedBounds.x, targetLocation.x);
                    textLayout.draw(g2D, targetLocation.x, targetLocation.y);
                    break;

                case TOP_RIGHT:
                case MIDDLE_RIGHT:
                case BOTTOM_RIGHT:
                    targetLocation.x = bounds.x + bounds.width - (int) textBounds.getWidth();
                    textLayout.draw(g2D, targetLocation.x, targetLocation.y);
                    consumedBounds.x = Math.min(consumedBounds.x, targetLocation.x);
                    break;
            }

            targetLocation.y += textLayout.getLeading() + textLayout.getDescent();
        }

        consumedBounds.height = targetLocation.y - consumedBounds.y;

        return consumedBounds;
    }

    /**
     * Calculates the next maximum index of the string that will be displayed.
     *
     * @param nextOffset    The index calculated using a
     * <code>LineBreakMeasurer</code> <i>nextOffset</i> method
     * @param measurerPosition  The position within a
     * <code>LineBreakMeasurer</code>
     * @param text  The text being rendered
     * @return  The next maximum index within the string
     */
    private static int nextTextIndex(int nextOffset, int measurerPosition, String text) {
        for (int i = measurerPosition + 1; i < nextOffset; ++i) {
            if (text.charAt(i) == '\n') {
                return i;
            }
        }

        return nextOffset;
    }
}

1 个答案:

答案 0 :(得分:0)

我使用的字体是OpenSansEmoji.ttf,它是3种字体的组合,现在它对我来说很好用。图像是通过文本和相应的表情符号生成的。

private void drawMessageString(Graphics2D g, final int messageHeight) {
        int x = CRUSH_PADDING + CRUSH_MESSAGE_LR_PADDING;
        int y = CRUSH_PADDING + TOP_BAR_HEIGHT + CRUSH_MESSAGE_TB_PADDING;

            String myString="he new guy from New Zealand who is playing tennis   ";


            try {
                byte ptext[] = myString.getBytes("UTF-8");
                    String value;
                value = new String(ptext, "UTF-8");
                TextRenderer.drawString(g, value, FontUtils.getInstance().getFont(FONT_OPEN_EMOJIFONT, 24.0f), MSG_COLOR, new Rectangle(x, y, CRUSH_MESSAGE_WIDTH, messageHeight), TextAlignment.TOP, TextFormat.FIRST_LINE_VISIBLE);

            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    }