Java examples for 2D Graphics:BufferedImage
Renders a Label and returns it as a BufferedImage.
/**/* w w w. j ava2 s. c o m*/ * This file is part of VoteBox. * * VoteBox is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by * the Free Software Foundation. * * You should have received a copy of the GNU General Public License * along with VoteBox, found in the root of any distribution or * repository containing all or part of VoteBox. * * THIS SOFTWARE IS PROVIDED BY WILLIAM MARSH RICE UNIVERSITY, HOUSTON, * TX AND IS PROVIDED 'AS IS' AND WITHOUT ANY EXPRESS, IMPLIED OR * STATUTORY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF * ACCURACY, COMPLETENESS, AND NONINFRINGEMENT. THE SOFTWARE USER SHALL * INDEMNIFY, DEFEND AND HOLD HARMLESS RICE UNIVERSITY AND ITS FACULTY, * STAFF AND STUDENTS FROM ANY AND ALL CLAIMS, ACTIONS, DAMAGES, LOSSES, * LIABILITIES, COSTS AND EXPENSES, INCLUDING ATTORNEYS' FEES AND COURT * COSTS, DIRECTLY OR INDIRECTLY ARISING OUR OF OR IN CONNECTION WITH * ACCESS OR USE OF THE SOFTWARE. */ //package com.java2s; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.font.FontRenderContext; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; public class Main { /** * The standard font to use */ public static final String FONT_NAME = "Lucida Sans"; /** * Renders a Label and returns it as a BufferedImage. * @param title is the text to be outputted * @param instructions are any instructions to be italized, such as '(please * select one)' * @param description are any descriptions (such as those used on * propositions) * @param fontsize the size of the font * @param wrappingWidth is the width at which the label should wrap * @param bold whether the label is bold * @param color is the color of the text * @param boxed is a boolean flag to determine whether or a box should be * placed around the label * @param titleCentered is a boolean flag as to whether or not the text * should be centered * @return the rendered Label */ public static BufferedImage renderLabel(String title, String instructions, String description, int fontsize, int wrappingWidth, Color color, boolean bold, boolean boxed, boolean titleCentered) { Font font = new Font(FONT_NAME, (bold) ? Font.BOLD : Font.PLAIN, fontsize); Font italicFont = new Font(FONT_NAME, Font.ITALIC, fontsize); Font bigBoldFont = new Font(FONT_NAME, Font.BOLD, fontsize + 4); BufferedImage wrappedImage = new BufferedImage(1000, 1000, BufferedImage.TYPE_INT_ARGB); Graphics2D graphs = wrappedImage.createGraphics(); graphs.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); graphs.setFont(font); graphs.setColor(color); int baseline = graphs.getFontMetrics().getAscent(); String[] titleWords = title.split(" "); int padding = 10; int heightPos = padding + baseline; int writePos = padding; int lineWidth = padding; int maxWidth = 0; // the max width of any line if (titleCentered) { graphs.setFont(bigBoldFont); String[][] splitText = spliteOnNewLineAndSpace(title); for (int y = 0; y < splitText.length; y++) { String[] line = splitText[y]; int margin = (wrappingWidth - 2 * padding - lineWidth(line, bigBoldFont)) / 2; graphs.drawString(stringArrayToString(line), writePos + margin, heightPos); heightPos += lineHeight("line", bigBoldFont); } } else { for (String word : titleWords) // For each word try placing it on // the line, // if not jump down a line and then write it { Rectangle2D measurement = font.getStringBounds(word + " ", new FontRenderContext(new AffineTransform(), true, true)); int wordWidth = (int) measurement.getWidth(); int wordHeight = (int) measurement.getHeight(); writePos = lineWidth; lineWidth += wordWidth; // TODO: this code does do what the comment above says it does! // It doesn't jump down a line on it's own! add this! // if the width of our word is longer than the entire line space, // break it up. if (wordWidth > wrappedImage.getWidth()) { String remainingStr = word; while (remainingStr.length() > wrappedImage.getWidth()) { graphs.drawString( remainingStr.substring(0, wrappedImage.getWidth()), writePos, heightPos); remainingStr = remainingStr.substring(wrappedImage .getWidth()); // we've just written one whole line. put our position variables back // at the beginning heightPos += wordHeight; writePos = padding; lineWidth = padding; } } else if (word.equals("\n") || word.equals("<newline>")) { maxWidth = Math.max(lineWidth, maxWidth); heightPos += wordHeight; writePos = padding; lineWidth = padding; } graphs.drawString(word + " ", writePos, heightPos); } } if (!instructions.equals("")) // write instructions on how to use { // heightPos+= lineHeight(instructions.split(" "), italicFont); String[][] splitText = spliteOnNewLineAndSpace(instructions); for (int y = 0; y < splitText.length; y++) { String[] line = splitText[y]; int margin = (wrappingWidth - 2 * padding - lineWidth(line, italicFont)) / 2; graphs.setFont(italicFont); graphs.drawString(stringArrayToString(line), writePos + margin, heightPos); heightPos += lineHeight("line", italicFont); } } if (!description.equals("")) // write description on how to use { heightPos += lineHeight("text", font); description = addInNewLines(description, font, wrappingWidth, padding); String[][] splitText = spliteOnNewLineAndSpace(description); graphs.setFont(font); for (int y = 0; y < splitText.length; y++) { String[] line = splitText[y]; graphs.drawString(stringArrayToString(line), writePos, heightPos); heightPos += lineHeight("line", font); } } maxWidth = Math.max(lineWidth, maxWidth); if (wrappingWidth != 0) // then wrap at the wrappingWidth or maxWidth maxWidth = Math.max(maxWidth, wrappingWidth); if (boxed) { graphs.setColor(Color.BLACK); graphs.setStroke(new BasicStroke(padding / 2)); graphs.drawRect(0, 0, maxWidth - 1, heightPos + padding - 1); } if (maxWidth < wrappedImage.getWidth()) { wrappedImage = wrappedImage.getSubimage(0, 0, maxWidth, heightPos + padding); } else { wrappedImage = wrappedImage.getSubimage(0, 0, wrappedImage.getWidth(), heightPos); } return copy(wrappedImage); } /** * Splits text on new line and then on white space * @param text the text to be split * @return the split text */ private static String[][] spliteOnNewLineAndSpace(String text) { String[] splitOnNewLine = text.split("<newline>"); String[][] splitText = new String[splitOnNewLine.length][0]; for (int x = 0; x < splitOnNewLine.length; x++) { splitText[x] = splitOnNewLine[x].split(" "); } return splitText; } /** * Calculates the line width at a given font * @param line is the line * @param font is the font * @return the width */ private static int lineWidth(String[] line, Font font) { int width = 0; for (String word : line) { Rectangle2D measurement = font .getStringBounds(word + " ", new FontRenderContext( new AffineTransform(), true, true)); width += measurement.getWidth(); } return width; } /** * Transforms an array of Strings to one string w/ appropriate spacing added * in between. Also trims the string to remove useless white sapce * @param array the array to be transformed * @return the array as a string */ private static String stringArrayToString(String[] array) { String currentString = new String(" "); for (int x = 0; x < array.length; x++) { currentString = currentString.concat(array[x] + " "); } return currentString.trim(); } /** * Calculates the line height at a given font, by looking at the height of * the first word * @param line is the line * @param font is the font * @return the height */ private static int lineHeight(String line, Font font) { Rectangle2D measurement = font.getStringBounds(line + " ", new FontRenderContext(new AffineTransform(), true, true)); return (int) measurement.getHeight(); } /** * A private helper to add in tags of where new lines should be added when a * text is rendered with at given font with a set wrappingWidth and padding * @param text the text to be redered * @param font the font to reder with * @param wrappingWidth the width at which to wrap * @param padding the padding that should be on the text * @return the text with appropriate <newline> tags added in */ private static String addInNewLines(String text, Font font, int wrappingWidth, int padding) { String copy = new String(""); String[] splitText = text.split(" "); int currentLineWidth = padding; for (String word : splitText) { Rectangle2D measurement = font .getStringBounds(word + " ", new FontRenderContext( new AffineTransform(), true, true)); currentLineWidth += measurement.getWidth(); if (currentLineWidth + padding > wrappingWidth) { currentLineWidth = (int) measurement.getWidth() + padding; copy = copy.concat(" <newline>"); } copy = copy.concat(word + " "); } return copy; } /** * Copies a buffered Image. Borrowed 100% from * http://cui.unige.ch/~deriazm/javasources/ImgTools.java I really can't * think of a better way of writing this code - so i just used theirs */ public static BufferedImage copy(BufferedImage bImage) { int w = bImage.getWidth(null); int h = bImage.getHeight(null); BufferedImage bImage2 = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = bImage2.createGraphics(); g2.drawImage(bImage, 0, 0, null); return bImage2; } }