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);
Related
I need to create an application with interface scaling. I have a button with icon inside and jpanel, that hold this button. The problem is that when scale is on - an icon is blurred and to fix this, I use downscaling in paintComponent. When system scale is on, I have normal image, as a result. But JPanel still have a scaled size. I tryed to override JPanel paintComponent too, but as a result I had too small buttons, because downscale on button and donwscale on JPanel work togeather. I can't use scale only from JPanel, when I click a button, it take a scaled size and image blurred again.
This is a simple example.
And the code is:
public class Test{
public static void main(String[] args) throws Exception{
System.setProperty("sun.java2d.uiScale", "1.5");
JFrame j = new JFrame();
Image img = ImageIO.read(new File("D:\\1.png"));
j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
j.setPreferredSize(new Dimension(300, 150));
j.setVisible(true);
j.setLocationRelativeTo(null);
j.setLayout(new BorderLayout());
img = img.getScaledInstance((int) (60 * 1.5),(int) (60 * 1.5),Image.SCALE_DEFAULT);
JToggleButton tb = new JToggleButton(){
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.scale(0.67,0.67);
super.paintComponent(g2);
}
};
tb.setIcon(new ImageIcon(img));
JToggleButton tb2 = new JToggleButton(){
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.scale(0.67,0.67);
super.paintComponent(g2);
}
};
tb2.setIcon(new ImageIcon(img));
JPanel jPanel = new JPanel(){
};
jPanel.setLayout(new GridLayout(1,1));
jPanel.add(tb);
jPanel.setBackground(Color.RED);
JPanel content = new JPanel();
content.setLayout(new FlowLayout());
content.add(jPanel);
j.setContentPane(content);
j.pack();
}
}
I use java10.
Thank you.
You render your UI with scaling factor of 1.5: all UI including icons and images is scaled so that it displays correctly on a High DPI display. If image does not scale, it would be too small for a higher DPI setting.
If your application supports High DPI displays, i.e. UI scaling, you should provide images of different resolutions. See MultiResolutionImage in Java 9.
You can find sample code in this answer to a related question.
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);
I want go full screen and keep everything inside in order.
How should i put the JFrame into full screen AND rescale everything inside: images, generated drawings etc.(sth like zooming it up so the content will fit the screen).
The problem is I am making full screen app, but I don't know on what screen it will be displayed.
This will put the frame into fullscreen, but the content will not be rescaled
frame.dispose();
frame.setUndecorated(true);
frame.setLocation(0, 0);
frame.setSize(java.awt.Toolkit.getDefaultToolkit().getScreenSize());
frame.setVisible(true);
frame.repaint();
Depends on what it is that you want to scale.
If its graphics you draw using Java2D, just figure out how much the stuff needs to be scaled up and use Graphics2D.scale() to scale the gfx appropiately.
If its something with a Swing layout, use a Layout manager to make an adaptive layout.
If its something else, elaborate on your problem
If this really is what you want to do (see warnings from other answers), it's not too hard to do (but takes a little time to figure out). Basically, it involves extending JPanel, and then overwriting the paint method.
Here's a sample that I came up with:
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class CustomPanel extends JPanel{
Component myComponent;
public CustomPanel(){
super();
setLayout(null);
}
/**
* Only allows one component to be added
*/
#Override
public Component add(Component c){
super.add(c);
c.setLocation(0, 0);
c.setSize(c.getPreferredSize());
myComponent = c;
return c;
}
#Override
public void paint(final Graphics g){
Dimension d = this.getSize();
Dimension p = myComponent.getPreferredSize();
// Paints the child component to a image
BufferedImage newImg = new BufferedImage(p.width, p.height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = newImg.createGraphics();
super.paint(g2d);
// Resizes the image if necessary
Image img;
if(d.height > p.height && d.width > p.width){
System.out.println("Scaled");
float changePercentage = 0;
if(d.height/p.height > d.width/p.width){
changePercentage = (float)d.width/(float)p.width;
} else{
changePercentage = (float)d.height/(float)p.height;
}
System.out.println(changePercentage);
int newHeight = ((Float)(p.height * changePercentage)).intValue();
int newWidth = ((Float)(p.width * changePercentage)).intValue();
img = newImg.getScaledInstance(newWidth, newHeight, 0);
} else{
System.out.println("Not Scaled");
img = newImg;
}
// Paints the image of the child component to the screen.
g.drawImage(img, 0, 0, null);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
SwingUtilities.invokeLater(new Runnable(){public void run(){
JFrame frame = new JFrame("Zoom Panel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 200);
CustomPanel buffer = new CustomPanel();
JPanel content = new JPanel();
content.add(new JLabel("Bogus"));
content.setBackground(Color.red);
buffer.add(content);
frame.setContentPane(buffer);
frame.setVisible(true);
new CustomPanel();
}});
}
}
few days back I just worked with an java full screen app. Have a look at the following link. if that was your requirement I can help you to some extent.
https://docs.google.com/open?id=0B9U-BwYu62ZaeDM3SWZhaTdSYzQ
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.
How to display an image to JPanel or to JLabel using the BufferedImage?
I load an Image using FileChooser and I need to display what I've loaded.
I don't extend my class to any container.
Override paintComponents(g) paintComponent(g) method of JPanel or JLabel and draw image in it. Something like follow:
JPanel panel = new JPanel(){
#Override
public void paintComponent(Graphics g) {
BufferedImage image = null; // get your buffered image.
Graphics2D graphics2d = (Graphics2D) g;
graphics2d.drawImage(image, 0, 0, null);
super.paintComponents(g);
}
};
Same thing for JLabel. Or in another way:
BufferedImage image = null; // get your buffered image.
ImageIcon icon = new ImageIcon((Image)image);
JLabel label = new JLabel();
label.setIcon(icon);
As you are saying that you are loading image from FileChooser it can be done in following
way:
ImageIcon icon = new ImageIcon(
fileChooser.getCurrentDirectory().toString()
+"/"+fileChooser.getSelectedFile().getName());
Now you can use ImageIcon in JLabel or add it in JPanel.
Above code is sample code and not tested so not necessary to run without error. You might need to change it as per your need.