5

I have seen that in photoshop text can be easily resized just by dragging them. How can we do the same thing in Java? Any idea on how to resize text in java? Added a snapshot of letter "A" resized in photoshop

enter image description here


Please let me know what is wrong with this code?

public class ResizeImage extends JFrame {

    public ResizeImage(){
        JPanel panel = new JPanel(){
            public void paintComponent(Graphics g) {
                // In your paint(Graphics g) method
                // Create a buffered image for use as text layer
                BufferedImage textLayer = new BufferedImage(240, 240, 
                                              BufferedImage.TYPE_INT_RGB);

                // Get the graphics instance of the buffered image
            Graphics2D gBuffImg = textLayer.createGraphics();

                // Draw the string
                gBuffImg.drawString("Hello World", 10, 10);

                // Rescale the string the way you want it
                gBuffImg.scale(200, 50);

                // Draw the buffered image on the output's graphics object
                g.drawImage(textLayer, 0, 0, null);
                gBuffImg.dispose();
            }
        };
        add(panel);
    }

    public static void main(String [] args){
        ResizeImage frame = new ResizeImage();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        frame.setSize(300, 300);
        frame.setVisible(true);
    }
} 
Matthieu
  • 2,736
  • 4
  • 57
  • 87
user001
  • 991
  • 6
  • 16
  • 34

5 Answers5

11

One way is to use an AffineTransform (this variant also fades the color).

Stretch (& fade) using a Serif font for the text

import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import javax.swing.*;
import java.io.File;
import javax.imageio.ImageIO;

public class StretchText {

    public static void main(String[] args) throws Exception {
        // used to stretch the graphics instance sideways
        AffineTransform stretch = new AffineTransform();
        int w = 640; // image width
        int h = 200; // image height
        int f = 21; // Font size in px
        String s = "The quick brown fox jumps over the lazy dog.";

        final BufferedImage bi = new BufferedImage(
                w,h,BufferedImage.TYPE_INT_RGB);
        Graphics2D g = bi.createGraphics();
        g.setFont(new Font("Serif",Font.PLAIN,f));
        g.setRenderingHint(
                RenderingHints.KEY_TEXT_ANTIALIASING, 
                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        // paint BG
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, w, h);
        g.setColor(Color.BLACK);

        for (int i=0; (i*f)+f<=h; i++) {
            g.drawString(s, 0, (i*f)+f);
            // stretch
            stretch.concatenate(
                    AffineTransform.getScaleInstance(1.18, 1d));
            g.setTransform(stretch);

            // fade
            Color c = g.getColor();
            g.setColor(new Color (
                    c.getRed(),
                    c.getGreen(),
                    c.getBlue(),
                    (int)(c.getAlpha()*.75)));
        }

        g.dispose();

        ImageIO.write(bi, "png", new File(
                new File(System.getProperty("user.home")), 
                "StretchText.png"));
        Runnable r = new Runnable() {
            @Override
            public void run() {
                JLabel gui = new JLabel(new ImageIcon(bi));
                JOptionPane.showMessageDialog(null, gui);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
4

You can use TextLayout to get the geometry, as shown here. The example scales the image to fill the frame. JInternalFrame might be a good choice to leverage the frame's resizing feature. Alternative, the example cited here shows how to click and drag multiple selections.

image

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Hi This is what I was looking. I will check this out and try to see that whether I can make it dynamic.. Thanks again – user001 Nov 18 '12 at 16:49
  • Perhaps add a `Timer` that stretches it from location by platform (default size) to screen-size, pixel by pixel? Though a title of 'Stretch Me' might also do it. ;) – Andrew Thompson Nov 19 '12 at 00:24
  • Hi I tried the above process of converting text to image and resizing it and it works absolutely fine. Now I am stuck with another issue i.e how to edit the text after converting it to an image. How to do that? – user001 Nov 21 '12 at 02:26
  • Note how the example calls `createImage()` when `setText()` gets called. – trashgod Nov 21 '12 at 02:30
  • Sorry Trashgod I couldn't get your point. Are you asking me to save the text somewhere before creating the image and then reuse the saved text again while editing? – user001 Nov 21 '12 at 02:37
  • No problem; whenever you change the label's text using `setText()`, a new image is generated via `createImage()`. – trashgod Nov 21 '12 at 02:39
  • But trashgod how is it going to help me? They are getting the text and converting it to image in createImage method.. But my question is how to edit it now? – user001 Nov 21 '12 at 02:58
3

u can define type of font

e.g.

Font f = new Font("SansSerif", Font.BOLD, 40)
Bhavik Ambani
  • 6,557
  • 14
  • 55
  • 86
DRastislav
  • 1,892
  • 3
  • 26
  • 40
  • Font size of 40 would increase both width and height of a letter. But as you can see in above image, only width is getting increased. How to achieve that? – user001 Nov 18 '12 at 13:01
1

Unfortunately the java api doesn't have a native free-form scaling/transform method fonts.

You can however rescale a BufferedImage or Graphics object with the scale(x, y) method. So you can try an approach with "layers" instead. I.e. draw objects, such as text, in their own layer (i.e. a BufferedImage) first and then on the actual graphics output.

So draw the text as usual on a BufferedImage and rescale it the way you want. Here is some simple sample code to get you starting.

// In your paint(Graphics g) method

// Create a buffered image for use as text layer
BufferedImage textLayer = new BufferedImage(240, 240, 
                                  BufferedImage.TYPE_INT_ARGB);

// Get the graphics instance of the buffered image
Graphics2D gBuffImg = buffImg.createGraphics();

// Draw the string
gBuffImg.drawString("Hello World", 0, 0);

// Rescale the string the way you want it
gBuffImg.scale(240, 120);

// Draw the buffered image on the output's graphics object
g.drawImage(gBuffImg, 0, 0, null);

The actual size of the text layer could be determined with the help of the FontMetrics object but I'll leave that as an exercise for the OP.

Spoike
  • 119,724
  • 44
  • 140
  • 158
0

This can be done at the Graphics level using Graphics.setTransform(). However I believe it is more obvious to do this at the Font level using the lesser known Font.deriveFont(transform). For example

// create transform
AffineTransform affineTransform = new AffineTransform();
affineTransform.scale(1d, 3d);

// create font using that transform
Font stretchedFont = g.getFont().deriveFont(affineTransform);

// set font as normal
g.setFont(stretchedFont);

// render as normal
g.drawString("Stretched", 23, 45);
Adam
  • 35,919
  • 9
  • 100
  • 137