Shrink image to fit around rotated text?
Hello everyone,
I'm a Java2D newbie and I just have this one image-related requirement to fulfill. Basically, I just need one line of text to be rotated 45 degrees and turned into an image. I've got the text rotation down, but right now it's based on a hard-coded image size. At runtime, I will have no idea how long the text string will be, but I want to the image size to be the minimum bounding box of the rotate text.
Any ideas? Thanks!!
What i have so far...
-
BufferedImage image = new BufferedImage(330,270, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
FontMetrics metrics = g.getFontMetrics();
int fontHeight = metrics.getHeight();
AffineTransform fontTransform = new AffineTransform();
fontTransform.rotate(-Math.toRadians(45));
Font textFont = new Font("Arial", Font.PLAIN,12);
Font reflectionFont = textFont.deriveFont( fontTransform);
g.setFont(reflectionFont);
g.drawString("Rotated Font", 15, image.getHeight() - fontHeight);
g.dispose();
[1076 byte] By [
lumberga] at [2007-11-27 9:24:20]

# 1
import java.awt.*;
import java.awt.event.*;
import java.awt.font.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class MinBounds implements ActionListener {
JLabel label;
double theta = 0;
double thetaInc = Math.toRadians(5);
BufferedImage image;
public void actionPerformed(ActionEvent e) {
theta += thetaInc;
label.setIcon(new ImageIcon(getImage()));
}
private BufferedImage getImage() {
double cos = Math.abs(Math.cos(theta));
double sin = Math.abs(Math.sin(theta));
int iw = image.getWidth();
int ih = image.getHeight();
double w = iw*cos + ih*sin;
double h = ih*cos + iw*sin;
int type = BufferedImage.TYPE_INT_RGB;
BufferedImage dest = new BufferedImage((int)w, (int)h, type);
Graphics2D g2 = dest.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2.setBackground(UIManager.getColor("Panel.background"));
g2.clearRect(0,0,(int)w,(int)h);
double x = (w - iw)/2;
double y = (h - ih)/2;
AffineTransform at = AffineTransform.getTranslateInstance(x,y);
at.rotate(theta, iw/2, ih/2);
g2.drawRenderedImage(image, at);
g2.dispose();
return dest;
}
private void makeImage() {
Font font = new Font("dialog", Font.PLAIN, 36);
String s = "Hello World";
FontRenderContext frc = new FontRenderContext(null, true, false);
float w = (float)font.getStringBounds(s, frc).getWidth();
LineMetrics lm = font.getLineMetrics(s, frc);
float h = lm.getAscent() + lm.getDescent();
int type = BufferedImage.TYPE_INT_RGB;
image = new BufferedImage((int)w, (int)h, type);
Graphics2D g2 = image.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setBackground(UIManager.getColor("Panel.background"));
g2.clearRect(0,0,(int)w,(int)h);
g2.setPaint(Color.blue);
g2.setFont(font);
g2.drawString(s, 0, lm.getAscent());
g2.dispose();
}
private JScrollPane getContent() {
label = new JLabel();
label.setHorizontalAlignment(JLabel.CENTER);
label.setBorder(BorderFactory.createEtchedBorder());
makeImage();
label.setIcon(new ImageIcon(getImage()));
JPanel panel = new JPanel(new GridBagLayout());
panel.add(label, new GridBagConstraints());
return new JScrollPane(panel);
}
private JPanel getLast() {
JButton button = new JButton("rotate");
button.addActionListener(this);
JPanel panel = new JPanel();
panel.add(button);
return panel;
}
public static void main(String[] args) {
MinBounds test = new MinBounds();
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(test.getContent());
f.getContentPane().add(test.getLast(), "Last");
f.setSize(400,400);
f.setLocation(200,200);
f.setVisible(true);
}
}