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
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);
}
}
One way is to use an AffineTransform (this variant also fades the color).
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);
}
}
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.
u can define type of font
e.g.
Font f = new Font("SansSerif", Font.BOLD, 40)
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.
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);
Related
I’ve been reading the API for Graphics2D and have seen examples of all the available composite modes (that are similar to photoshop blend modes) but I can’t see a way to draw a source image to a target buffered image In a colour that I have specified, for example my source image is a white opaque circle on a fully transparent background, how do I draw using this to a buffer so a coloured circle is drawn.
I would prefer not to construct an intermediate image for performance reasons, is this possible with the api?
EDIT: I have added an image that hopefully helps to show the operation I am trying to describe. This is a common way to draw sprites in open GL etc and I am just wondering how to use the Graphics2D API to do the same thing.
Is is possible using the API but you have to write your own ImageProducer subclass similar to FilteredImageSource but with two input images instead of one. But because of that the end result will require more lines of code than a manual implementation and won't be any more efficient. Alternatively you can use the existing FilteredImageSource and write an ImageFilter subclass that wraps the 2nd image and does the hard work.
Poke me if you decide you want to go with any of these routes.
Specify the location of your image in the imageName below.
public class ColoredCircle extends JPanel {
JFrame frame = new JFrame();
BufferedImage buf;
String imageName = "F://ngc_1300_spiral.jpg";
public static void main(String[] args) {
new ColoredCircle().start();
}
int scale = 10;
public void start() {
try {
buf = ImageIO.read(new File(imageName));
}
catch (IOException ioe) {
ioe.printStackTrace();
}
setPreferredSize(
new Dimension(buf.getWidth() / scale, buf.getHeight() / scale));
frame.add(this);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(buf,
0,
0,
buf.getWidth() / scale,
buf.getHeight() / scale,
null);
g2d.dispose();
}
}
I want to re-size my ImageIcon to fit my jLabel. Using the answer from this post Scale the ImageIcon automatically to label size I am using
public jfrmHome() {
initComponents();
this.setLocationRelativeTo(null);
ImageIcon iconimage;
iconimage = new ImageIcon(getClass().getResource("/org/me/musiconweb/resources/Music-icon.png"));
BufferedImage bi = new BufferedImage(iconimage.getIconWidth(), iconimage.getIconHeight(), BufferedImage.TYPE_INT_RGB);
Graphics g = bi.createGraphics();
iconimage.paintIcon(null, g, 0,0);
g.dispose();
BufferedImage resizedimage=resize(bi,jlblPicture.getWidth(), jlblPicture.getHeight());
ImageIcon resizedicon=new ImageIcon(resizedimage);
jlblPicture.setIcon(resizedicon);
}
This re-sizes the Image but i have a little problem. The background of the image becomes black instead of white that it was
This
turns to
Please what am i doing wrong?
That image has transparency. So change BufferedImage.TYPE_INT_RGB to BufferedImage.TYPE_INT_ARGB
It is not obvious at SO on a white BG, but try this SSCCE & it becomes more clear..
import java.net.URL;
import javax.swing.*;
class ShowImage {
public static void main(String[] args) throws Exception {
final URL url = new URL("http://i.stack.imgur.com/1yeUy.png");
Runnable r = new Runnable() {
#Override
public void run() {
JLabel l = new JLabel(new ImageIcon(url));
JOptionPane.showMessageDialog(null, l);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency
SwingUtilities.invokeLater(r);
}
}
Your image has a transparent background. Therefore it shows as black when drawn on a newly created opaque image. Use
g.setColor(Color.WHITE);
g.fillRect(0, 0, jlblPicture.getWidth(), jlblPicture.getHeight());
if you want a white background. For transparent background, draw on TYPE_INT_ARGB image instead.
Try out these codes
ImageIcon icon1 = new
ImageIcon(getClass().getResource("\\image\\"+f1.getName()));
BufferedImage bi = new
BufferedImage(icon1.getIconWidth(),icon1.getIconHeight()
, BufferedImage.TYPE_INT_RGB);
Graphics g = bi.createGraphics();
icon1.paintIcon(null, g, 0,0);
g.dispose();`
//image resizing code...............>
ImageIcon resizedicon=new ImageIcon(bi.getScaledInstance(imglbl.getWidth(),
imglbl.getHeight(),1 ));
imglbl.setBackground(new java.awt.Color(255, 255, 255));
imglbl.setIcon(resizedicon);
I have an imagepanel class that draws an image on a JPanel. My problem is that the image appears to be very small inside the jpanel, and I dont know why.
I have done all I could and searched the net and even some java books for this little problem but to no success. I really need some help on this one.
I am extremely new to java.
class Weapons extends JPanel {
private Image weaponimage = weapon1.getImage();
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null)
g.drawImage(weaponimage, 0, 0, getWidth(), getHeight(), this);
}
}
that's the image class.
The 'instant fix' is to paint that element at its natural size. E.G. Change this:
g.drawImage(weaponimage, 0, 0, getWidth(), getHeight(), this);
To this:
g.drawImage(weaponimage, 0, 0, this);
Which seems logical. A 'weapon' should probably be drawn at natural size.
..problem is that the image appears to be very small inside the jpanel,
No. The problem seems to be that the panel itself is very small. The image is painted the width and height of the panel as assigned by the layout.
To increase the size of the (BG) image, add components to the panel (properly laid out) and display the panel at its preferred size.
May be your class look like this:
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
class Weapons extends JPanel {
// get image according to your application logic
BufferedImage image;
#Override
public void paint(Graphics g){
super.paintComponent(g);
g.drawImage(image, 0, 0, getWidth() - 1, getHeight() - 1, 0, 0, image.getWidth() - 1, image.getHeight() - 1, null);
}
public void setImage(BufferedImage image){
this.image = image;
}
}
class Main {
Weapons weapons;
public void updateWeapons(){
// create image
BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_3BYTE_BGR);
// draw on image
// TO UPDATE WEAPONS GUI, below steps are impotant
weapons.setImage(image);
weapons.repaint();
}
}
You have to override paint() method. Then you can set image and call repaint() to update graphics on panel.
use a dimension object to change the size of the image
Weapons picture = new Weapons();
picture.setPreferredSize(new Dimension(110, 160));
panel.add(picture);
do this and you can stretch the length and breadth of your photo as needed.
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Java Swing : Obtain Image of JFrame
I am working on a little drag-and-drop Java GUI builder. It works so far, but the widgets I'm dragging and dropping are just rectangles I'm dynamically drawing on a canvas.
If I have a rectangle that represents a widget like a JButton, is there a way for me to create a JButton, set the size and get the image of that JButton if it was drawn on the screen? Then I could paint the image to the screen instead of just my boring rectangle.
For example, I'm currently doing this to draw a (red) rectangle:
public void paint(Graphics graphics) {
int x = 100;
int y = 100;
int height = 100;
int width = 150;
graphics.setColor(Color.red);
graphics.drawRect(x, y, height, width);
}
How can I do something like:
public void paint(Graphics graphics) {
int x = 100;
int y = 100;
int height = 100;
int width = 150;
JButton btn = new JButton();
btn.setLabel("btn1");
btn.setHeight(height); // or minHeight, or maxHeight, or preferredHeight, or whatever; swing is tricky ;)
btn.setWidth(width);
Image image = // get the image of what the button will look like on screen at size of 'height' and 'width'
drawImage(image, x, y, imageObserver);
}
Basically, you'll paint your component to an image, and then paint that image wherever you want. In this case it's okay to call paint directly because you're not painting to the screen (but to a memory location).
If you wanted to optimize your code more than I've done here, you can save the image, and just repaint it in a different location whenever it's moved (instead of calculating the image from the button every time the screen repaints).
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class MainPanel extends Box{
public MainPanel(){
super(BoxLayout.Y_AXIS);
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
// Create image to paint button to
BufferedImage buttonImage = new BufferedImage(100, 150, BufferedImage.TYPE_INT_ARGB);
final Graphics g2d = buttonImage.getGraphics();
// Create button and paint it to your image
JButton button = new JButton("Click Me");
button.setSize(button.getPreferredSize());
button.paint(g2d);
// Draw image in desired location
g.drawImage(buttonImage, 100, 100, null);
}
public static void main(String[] args){
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new MainPanel());
frame.pack();
frame.setSize(400, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
my goal is to draw some bufferedimage onto another. then all this stuff draw onto some other bufferedimage and so on. And finally draw this on top of a panel.
For now i'm trying to draw bufferedimage onto panel and nothing works. My bufferedimage looks completely white:
public class Main2 {
public static void main(String[] args) {
JFrame frame = new JFrame("asdf");
final JPanel panel = (JPanel) frame.getContentPane();
frame.setSize(500,500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
panel.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
somepaint(panel);
}
});
}
private static void somepaint(JPanel panel) {
BufferedImage image = new BufferedImage(200,200,BufferedImage.TYPE_INT_ARGB);
image.getGraphics().setColor(Color.red);
image.getGraphics().fillRect(0, 0, 200, 200);
Graphics2D graphics = (Graphics2D) panel.getGraphics();
graphics.setColor(Color.magenta);
graphics.fillRect(0, 0, 500, 500);
graphics.drawImage(image, null, 0, 0); // draws white square instead of red one
}
}
thanks
Re:
private static void somepaint(JPanel panel) {
BufferedImage image = new BufferedImage(200,200,BufferedImage.TYPE_INT_ARGB);
image.getGraphics().setColor(Color.red);
image.getGraphics().fillRect(0, 0, 200, 200);
Graphics2D graphics = (Graphics2D) panel.getGraphics();
This is not how you draw inside of a JPanel or JComponent.
Don't call getGraphics() on a component as the Graphics object returned will be short-lived, and anything drawn with it will not persist. Instead do your JPanel's drawing inside of its paintComponent(Graphics G) method override. You will need to create a class that extends JPanel in order to override paintComponent(...).
Most importantly, to see how to do Swing graphics correctly, don't guess. You'll want to read the Swing Graphics Tutorials first as it will require you to toss out some incorrect assumptions (I know that this is what I had to do to get it right).
You need to rectify your parameters in the drawImage() call. Change this:
graphics.drawImage(image, null, 0, 0);
to
graphics.drawImage(image, 0, 0,null);
Check the Java docs for more details.