Adjust image size to completely fit jFrame - java

I want to adjust the size of logo2.png so that it completely fits to the jFrame. Can anyone help me out?
jLabel2 = new javax.swing.JLabel();
jLabel2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Banking/logo2.png"))); // NOI18N
JDesktopPane.add(jLabel2);
jLabel2.setBounds(0, 0, 500, 290);

JLabel doesn't rescale it's content (ie the image), for that, you're going to have to get you hands a little dirty...
There are a number of ways to achieve this. Personally, I'd start with a custom component, which extends from something like JPanel which takes a base image and is capable of scaling and painting it.
Take a look at Performing Custom Painting and Painting in AWT and Swing for more details about performing custom painting.
Scaling an image is not as straightforward as it might seem, while Java does provide some APIs to scale images, generally, they don't generate fantastic results. Take a look at Quality of Image after resize very low -- Java and The Perils of Image.getScaledInstance() for more details.
I would normally recommend taking a look at the imgscalr library, as it's results are generally quite good (better then what the base Java API provides or I've seen through most other methods), but for this example, I've included an example of a divide an conqure approach.
This example provides a "scale to fill" implementation, this ensures that the resulting image ALWAYS fills the available space while maintaining it's aspect ratio, see Java: maintaining aspect ratio of JPanel background image for more discussions on the subject
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.HeadlessException;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ScaledBackground {
public static void main(String[] args) {
new ScaledBackground();
}
public ScaledBackground() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
try {
BufferedImage img = ImageIO.read(...);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new ImagePane(img));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException exp) {
exp.printStackTrace();
}
}
});
}
public class ImagePane extends JPanel {
private BufferedImage original;
private BufferedImage scaled;
public ImagePane(BufferedImage img) {
original = img;
scaled = original;
}
#Override
public Dimension getPreferredSize() {
return original == null ? new Dimension(200, 200) : new Dimension(original.getWidth(), original.getHeight());
}
#Override
public void invalidate() {
super.invalidate();
generateScaledInstance();
}
protected void generateScaledInstance() {
if (original != null) {
scaled = getScaledInstanceToFill(original, getSize());
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (scaled != null) {
int x = (getWidth() - scaled.getWidth()) / 2;
int y = (getHeight() - scaled.getHeight()) / 2;
g2d.drawImage(scaled, x, y, this);
}
g2d.dispose();
}
public BufferedImage getScaledInstanceToFill(BufferedImage img, Dimension size) {
float scaleFactor = getScaleFactorToFill(img, size);
return getScaledInstance(img, scaleFactor);
}
public float getScaleFactorToFill(BufferedImage img, Dimension size) {
float scale = 1f;
if (img != null) {
int imageWidth = img.getWidth();
int imageHeight = img.getHeight();
scale = getScaleFactorToFill(new Dimension(imageWidth, imageHeight), size);
}
return scale;
}
public float getScaleFactorToFill(Dimension original, Dimension toFit) {
float scale = 1f;
if (original != null && toFit != null) {
float dScaleWidth = getScaleFactor(original.width, toFit.width);
float dScaleHeight = getScaleFactor(original.height, toFit.height);
scale = Math.max(dScaleHeight, dScaleWidth);
}
return scale;
}
public float getScaleFactor(int iMasterSize, int iTargetSize) {
float scale = 1;
if (iMasterSize > iTargetSize) {
scale = (float) iTargetSize / (float) iMasterSize;
} else {
scale = (float) iTargetSize / (float) iMasterSize;
}
return scale;
}
public BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor) {
BufferedImage imgBuffer = null;
imgBuffer = getScaledInstance(img, dScaleFactor, RenderingHints.VALUE_INTERPOLATION_BILINEAR, true);
return imgBuffer;
}
protected BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor, Object hint, boolean higherQuality) {
BufferedImage scaled = img;
if (dScaleFactor != 1.0) {
if (dScaleFactor > 1.0) {
scaled = getScaledUpInstance(img, dScaleFactor, hint, higherQuality);
} else if (dScaleFactor > 0.0) {
scaled = getScaledDownInstance(img, dScaleFactor, hint, higherQuality);
}
}
return scaled;
}
protected BufferedImage getScaledDownInstance(BufferedImage img, double dScaleFactor, Object hint, boolean higherQuality) {
int targetWidth = (int) Math.round(img.getWidth() * dScaleFactor);
int targetHeight = (int) Math.round(img.getHeight() * dScaleFactor);
int type = (img.getTransparency() == Transparency.OPAQUE)
? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage ret = (BufferedImage) img;
if (targetHeight > 0 || targetWidth > 0) {
int w, h;
if (higherQuality) {
w = img.getWidth();
h = img.getHeight();
} else {
w = targetWidth;
h = targetHeight;
}
do {
if (higherQuality && w > targetWidth) {
w /= 2;
if (w < targetWidth) {
w = targetWidth;
}
}
if (higherQuality && h > targetHeight) {
h /= 2;
if (h < targetHeight) {
h = targetHeight;
}
}
BufferedImage tmp = new BufferedImage(Math.max(w, 1), Math.max(h, 1), type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(ret, 0, 0, w, h, null);
g2.dispose();
ret = tmp;
} while (w != targetWidth || h != targetHeight);
} else {
ret = new BufferedImage(1, 1, type);
}
return ret;
}
protected BufferedImage getScaledUpInstance(BufferedImage img,
double dScaleFactor,
Object hint,
boolean higherQuality) {
int targetWidth = (int) Math.round(img.getWidth() * dScaleFactor);
int targetHeight = (int) Math.round(img.getHeight() * dScaleFactor);
int type = BufferedImage.TYPE_INT_ARGB;
BufferedImage ret = (BufferedImage) img;
int w, h;
if (higherQuality) {
w = img.getWidth();
h = img.getHeight();
} else {
w = targetWidth;
h = targetHeight;
}
do {
if (higherQuality && w < targetWidth) {
w *= 2;
if (w > targetWidth) {
w = targetWidth;
}
}
if (higherQuality && h < targetHeight) {
h *= 2;
if (h > targetHeight) {
h = targetHeight;
}
}
BufferedImage tmp = new BufferedImage(w, h, type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(ret, 0, 0, w, h, null);
g2.dispose();
ret = tmp;
tmp = null;
} while (w != targetWidth || h != targetHeight);
return ret;
}
}
}
This example will grow and shrink as the image as the amount of available space for the panel changes

You can use the Stretch Icon on your JLabel.
Or you could use the Background Panel to draw the image.
In both cases the Image will shrink or grow as the frame is resized.

First get the Image, then use this method:
yourImage.getScaledInstance(newWidth, newHeight, Image.SCALE_DEFAULT);
You can get the width and height from the JFrame. Then you can convert the Image to ImageIcon and add it.

Related

Resize JLabel to fit JInternalFrame with an image in it

How to resize an image with JLabel resizing in an internal frame?
I tried some code that I found on the Internet like:
public static BufferedImage resize(Image image, int width, int height) {
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TRANSLUCENT);
Graphics2D g2d = (Graphics2D) bi.createGraphics();
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
g2d.drawImage(image, 0, 0, width, height, null);
g2d.dispose();
return bi;
or
getScaledInstance(l.getWidth(), -1, Image.SCALE_SMOOTH);
the code's result
But it only makes the image smaller.
Is there a way to resize the image with the JLabel and JInternalFrame? Any help is welcome :)
Scaling an image, well, is not simple. Take a look at:
Java: maintaining aspect ratio of JPanel background image
Scale the ImageIcon automatically to label size
Quality of Image after resize very low -- Java
Scaling can also be expensive, so you'd probably want someway to reduce the number of attempts (as a window been re-resized will be bombarded with a large number of sizing events).
The overall method is the same regardless if your using a JFrame, JPanel or JInternalFrame.
You need some way to monitor for the size changes and some way to determine when it might be a suitable time to scale the image. The following example make use of a ComponentListener and non-repeating Swing Timer. This allows us the ability to schedule a task to be executed in the future, but which can be cancelled if we need to.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
BufferedImage image = ImageIO.read(getClass().getResource("/images/happy.png"));
JInternalFrame internalFrame = new JInternalFrame("Test", true, true, true, true);
internalFrame.add(new ImagePane(image));
internalFrame.pack();
internalFrame.setVisible(true);
JDesktopPane desktopPane = new JDesktopPane();
desktopPane.add(internalFrame);
JFrame frame = new JFrame();
frame.add(desktopPane);
frame.setSize(new Dimension(800, 800));
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
public class ImagePane extends JPanel {
private Timer resizeTimer;
private BufferedImage masterImage;
private JLabel label;
private Scaler scaler;
public ImagePane(BufferedImage masterImage) {
this.masterImage = masterImage;
label = new JLabel(new ImageIcon(masterImage));
scaler = new Scaler(masterImage);
resizeTimer = new Timer(250, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
label.setIcon(new ImageIcon(scaler.getScaledInstanceToFill(getSize())));
}
});
resizeTimer.setRepeats(false);
addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent e) {
resizeTimer.restart();
}
});
setLayout(new BorderLayout());
add(label);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public class Scaler {
private BufferedImage master;
private Dimension masterSize;
private Map<RenderingHints.Key, Object> renderingHints = new HashMap<>();
public Scaler(BufferedImage master) {
this.master = master;
masterSize = new Dimension(master.getWidth(), master.getHeight());
renderingHints.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
renderingHints.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
renderingHints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
renderingHints.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
renderingHints.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
renderingHints.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
renderingHints.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
renderingHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
renderingHints.put(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
}
public BufferedImage getScaledInstanceToFit(Dimension size) {
return getScaledInstance(getScaleFactorToFit(size));
}
public BufferedImage getScaledInstanceToFill(Dimension size) {
return getScaledInstance(getScaleFactorToFill(size));
}
protected double getScaleFactor(int masterSize, int targetSize) {
return (double) targetSize / (double) masterSize;
}
protected double getScaleFactorToFit(Dimension toFit) {
double dScaleWidth = getScaleFactor(masterSize.width, toFit.width);
double dScaleHeight = getScaleFactor(masterSize.height, toFit.height);
return Math.min(dScaleHeight, dScaleWidth);
}
protected double getScaleFactorToFill(Dimension targetSize) {
double dScaleWidth = getScaleFactor(masterSize.width, targetSize.width);
double dScaleHeight = getScaleFactor(masterSize.height, targetSize.height);
return Math.max(dScaleHeight, dScaleWidth);
}
protected BufferedImage getScaledInstance(double dScaleFactor) {
BufferedImage imgScale = master;
int targetWidth = (int) Math.round(masterSize.getWidth() * dScaleFactor);
int targetHeight = (int) Math.round(masterSize.getHeight() * dScaleFactor);
if (dScaleFactor <= 1.0d) {
imgScale = getScaledDownInstance(targetWidth, targetHeight);
} else {
imgScale = getScaledUpInstance(targetWidth, targetHeight);
}
return imgScale;
}
protected BufferedImage getScaledDownInstance(
int targetWidth,
int targetHeight) {
int type = (master.getTransparency() == Transparency.OPAQUE)
? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage scaled = master;
if (targetHeight > 0 || targetWidth > 0) {
int width = master.getWidth();
int height = master.getHeight();
do {
if (width > targetWidth) {
width /= 2;
if (width < targetWidth) {
width = targetWidth;
}
}
if (height > targetHeight) {
height /= 2;
if (height < targetHeight) {
height = targetHeight;
}
}
BufferedImage tmp = new BufferedImage(Math.max(width, 1), Math.max(height, 1), type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHints(renderingHints);
g2.drawImage(scaled, 0, 0, width, height, null);
g2.dispose();
scaled = tmp;
} while (width != targetWidth || height != targetHeight);
} else {
scaled = new BufferedImage(1, 1, type);
}
return scaled;
}
protected BufferedImage getScaledUpInstance(
int targetWidth,
int targetHeight) {
int type = BufferedImage.TYPE_INT_ARGB;
BufferedImage ret = (BufferedImage) master;
int width = master.getWidth();
int height = master.getHeight();
do {
if (width < targetWidth) {
width *= 2;
if (width > targetWidth) {
width = targetWidth;
}
}
if (height < targetHeight) {
height *= 2;
if (height > targetHeight) {
height = targetHeight;
}
}
BufferedImage tmp = new BufferedImage(width, height, type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHints(renderingHints);
g2.drawImage(ret, 0, 0, width, height, null);
g2.dispose();
ret = tmp;
} while (width != targetWidth || height != targetHeight);
return ret;
}
}
}
Also, JLabel is actually irrelevant to your problem and I'd probably use a custom painting workflow to render the scaled image, but that's me.

Rotating Ball loses sharpness and colors

package testIDE;
import java.awt.BorderLayout;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import Utils.MyJFrame;
public class ExampleClass {
public static void main(String[] args) {
JFrame ballRotate = new BallRotate();
}
}
class BallRotate extends MyJFrame {
ArrayList<Integer> degree = new ArrayList<Integer>();
BufferedImage backGroundImage = getBufferedImage("testIDE/buttonDefaultImage.jpg");
JLabel backGroundLabel = new JLabel(new ImageIcon(backGroundImage));
BufferedImage footballImage = getBufferedImage("testIDE/Tennis_Ball.png");
int x = 0;
public BallRotate() {
footballImage=getScaledImage(250, 250, footballImage);
BufferedImage rotatedImage = footballImage;
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridBagLayout());
setLabel();
add(backGroundLabel);
pack();
centeringWindow();
setVisible(true);
setArray();
while (true) {
setDelay(60);
rotatedImage = rotateImage(rotatedImage, x);
setMyFuckingLabel(rotatedImage);
x += 10;
if (x == 10000) {
break;
}
}
}
private void setArray() {
for (int i = 0; i <= 360; i += 40) {
degree.add(i);
}
}
private void setLabel() {
JPanel footBallPanel = new JPanel(new BorderLayout());
JLabel footBallLabel = new JLabel(new ImageIcon(footballImage));
footBallPanel.add(footBallLabel);
borderingJPanel(footBallPanel, null, null);
backGroundLabel.setLayout(new GridBagLayout());
backGroundLabel.add(footBallPanel);
}
private BufferedImage rotateImage(BufferedImage buffImage, int degree) {
BufferedImage rotatedImage = null;
AffineTransform affineTransform = AffineTransform.getRotateInstance(
Math.toRadians(15*Math.PI), buffImage.getWidth() / 2,
buffImage.getHeight() / 2);
System.out.println(degree*Math.toRadians(1));
rotatedImage = new BufferedImage(buffImage.getWidth(),
buffImage.getHeight(), buffImage.getType());
Graphics2D g = (Graphics2D) rotatedImage.getGraphics();
g.setTransform(affineTransform);
g.drawImage(buffImage, 0, 0, null);
return rotatedImage;
}
public void setMyLabel(BufferedImage rotatedBuffImage) {
JLabel backgroundlabel = (JLabel) getContentPane().getComponent(0);
JPanel footBallPanel = (JPanel) backgroundlabel.getComponent(0);
JLabel footBallLabel = (JLabel) footBallPanel.getComponent(0);
footBallLabel.setIcon(new ImageIcon(rotatedBuffImage));
}
}
As you can see, my rotating tennis ball looses his form and his colouring. It seems to be that the colours are rotating also.
Why? And is there a way to prevent this? Ive posted the code which generated the dialog above.
Thanks for any help.
So a raft of issues...
Scaling an image in a single step is never a good idea (unless you only scaling by 50%). Java also isn't particular good at it. There are tricks you can employee, like using a multi-step scale (demonstrated within the example) or use an external library like imgscalr. See The Perils of Image.getScaledInstance() for more details.
You should avoid apply effects to the same image multiply times, this simply compounds the changes and will reduce the quality of the image. Instead, maintain a master image as close to the original as you can and use it, so you're always starting from the same starting point.
Swing is not thread safe. This means three things. First, you should never do anything within the context of the Event Dispatching Thread that might block it, like infinite loops. Second, you should only ever change the state of UI components from within the context of the EDT and third, you should make sure you are creating your UIs from within the context of the EDT. See Concurrency in Swing and Initial Threads for more details...
Any thing other then a straight horizontal or vertical line is going to look pretty...ordinary under the default rendering settings. You're going to need to supply some RenderingHints to enhance the result
This then raises the question of how do you do animation in Swing? Well, you have two basic options, you can use a Thread of some kind, which requires you to manually synchronise updates back to the EDT or you can use a Swing javax.swing.Timer, which allows you to schedule call backs at regular intervals which are triggered within the context of the EDT. Take a look at How to use Swing Timers for more details...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class BallRotate {
public static void main(String[] args) {
new BallRotate();
}
public BallRotate() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage master;
private JLabel ball;
private BufferedImage rotatedImage;
private float angle = 0;
private float delta = 5;
public TestPane() {
setLayout(new GridBagLayout());
try {
master = ImageIO.read(getClass().getResource("/Ball.png"));
master = getScaledInstanceToFit(master, new Dimension(250, 250));
} catch (IOException ex) {
ex.printStackTrace();
}
ImageIcon icon = new ImageIcon(getRotatedImage(0));
ball = new JLabel(icon);
add(ball);
Timer timer = new Timer(40, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
angle += delta;
// ball.setIcon(new ImageIcon(getRotatedImage(delta)));
getRotatedImage(angle);
ball.repaint();
System.out.println(angle);
}
});
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
timer.start();
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
protected BufferedImage getRotatedImage(float degree) {
if (rotatedImage == null) {
rotatedImage = new BufferedImage(master.getWidth(),
master.getHeight(), BufferedImage.TYPE_INT_ARGB);
}
AffineTransform affineTransform = AffineTransform.getRotateInstance(
Math.toRadians(degree), rotatedImage.getWidth() / 2,
rotatedImage.getHeight() / 2);
Graphics2D g = (Graphics2D) rotatedImage.getGraphics();
g.setBackground(new Color(255, 255, 255, 0));
g.clearRect(0, 0, rotatedImage.getWidth(), rotatedImage.getHeight());
g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g.setTransform(affineTransform);
g.drawImage(master, 0, 0, null);
g.dispose();
return rotatedImage;
}
}
public static BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor) {
return getScaledInstance(img, dScaleFactor, RenderingHints.VALUE_INTERPOLATION_BILINEAR, true);
}
protected static BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor, Object hint, boolean bHighQuality) {
BufferedImage imgScale = img;
int iImageWidth = (int) Math.round(img.getWidth() * dScaleFactor);
int iImageHeight = (int) Math.round(img.getHeight() * dScaleFactor);
// System.out.println("Scale Size = " + iImageWidth + "x" + iImageHeight);
if (dScaleFactor < 1.0d) {
imgScale = getScaledDownInstance(img, iImageWidth, iImageHeight, hint, bHighQuality);
}
return imgScale;
}
protected static BufferedImage getScaledDownInstance(BufferedImage img,
int targetWidth,
int targetHeight,
Object hint,
boolean higherQuality) {
int type = (img.getTransparency() == Transparency.OPAQUE)
? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage ret = (BufferedImage) img;
if (targetHeight > 0 || targetWidth > 0) {
int w, h;
if (higherQuality) {
// Use multi-step technique: start with original size, then
// scale down in multiple passes with drawImage()
// until the target size is reached
w = img.getWidth();
h = img.getHeight();
} else {
// Use one-step technique: scale directly from original
// size to target size with a single drawImage() call
w = targetWidth;
h = targetHeight;
}
do {
if (higherQuality && w > targetWidth) {
w /= 2;
if (w < targetWidth) {
w = targetWidth;
}
}
if (higherQuality && h > targetHeight) {
h /= 2;
if (h < targetHeight) {
h = targetHeight;
}
}
// if (w <= 0) w = 1;
// if (h <= 0) h = 1;
BufferedImage tmp = new BufferedImage(Math.max(w, 1), Math.max(h, 1), type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(ret, 0, 0, w, h, null);
g2.dispose();
ret = tmp;
} while (w != targetWidth || h != targetHeight);
} else {
ret = new BufferedImage(1, 1, type);
}
return ret;
}
public static double getScaleFactor(int iMasterSize, int iTargetSize) {
return (double) iTargetSize / (double) iMasterSize;
}
public static double getScaleFactorToFit(Dimension original, Dimension toFit) {
double dScale = 1d;
if (original != null && toFit != null) {
double dScaleWidth = getScaleFactor(original.width, toFit.width);
double dScaleHeight = getScaleFactor(original.height, toFit.height);
dScale = Math.min(dScaleHeight, dScaleWidth);
}
return dScale;
}
public static double getScaleFactorToFit(BufferedImage img, Dimension size) {
double dScale = 1;
if (img != null) {
int imageWidth = img.getWidth();
int imageHeight = img.getHeight();
dScale = getScaleFactorToFit(new Dimension(imageWidth, imageHeight), size);
}
return dScale;
}
public static BufferedImage getScaledInstanceToFit(BufferedImage img, Dimension size) {
double scaleFactor = getScaleFactorToFit(img, size);
return getScaledInstance(img, scaleFactor);
}
}

java making a screen shot preview with JPanel

I'm making a fun little test screen recording program in java, and I want it to have a preview of your screen before you start recording.. but its a very slow and poor method of which I am using, involving capturing an image, saving it, then reading it in through a bufferedimage and drawing that image using Graphics. Its very slow and not useful as a "preview" is there a way to speed up and have a more efficient "previewing system".
Here is what I have so far:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class MainFrame implements ActionListener, Runnable {
//add frame components
public static JFrame frame = new JFrame("Screen Caper - v1.0.1");
JButton start = new JButton("record");
JButton close = new JButton("Exit");
JPanel preview = new JPanel();
public static boolean running = false;
public static boolean recording = false;
public static boolean paused = false;
public static String curDir = System.getProperty("user.dir");
//get the screen width
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double width = screenSize.getWidth();
double height = screenSize.getHeight();
Container a = new Container();
Container b = new Container();
public MainFrame() {
frame.setSize((int)(width) - 80, (int)(height) - 80);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//setup the buttons and JPanel
a.setLayout(new GridLayout(1, 2));
a.add(start);
start.addActionListener(this);
a.add(close);
close.addActionListener(this);
frame.add(a, BorderLayout.NORTH);
b.setLayout(new GridLayout(1, 2));
b.add(preview);
frame.add(b, BorderLayout.CENTER);
//add anything else
running = true;
//set frame to visible
frame.setVisible(true);
run();
}
public static void main(String[] args) {
new MainFrame();
}
public void run() {
Graphics g = frame.getGraphics();
while (running) {
//draw the preview of the computer screen on the JPanel if its not recording already
if (!recording && !paused) {
drawPreview(g);
}
}
}
public void drawPreview(Graphics g) {
BufferedImage image;
try {
image = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
ImageIO.write(image, "png", new File("test.png"));
} catch (Exception ex) {
ex.printStackTrace();
}
BufferedImage prevIm;
try {
prevIm = ImageIO.read(new File("test.png"));
g.setColor(new Color(0, 0, 0));
g.fillRect(preview.getX() + 3, preview.getY() + 51, preview.getWidth(), preview.getHeight() + 1);
g.drawImage(prevIm, preview.getX() + 3, preview.getY() + 51, preview.getX() + preview.getWidth(), preview.getY() + preview.getHeight(), null);
} catch (IOException ex) {
ex.printStackTrace();
}
}
public void record(Graphics g) {
}
#Override
public void actionPerformed(ActionEvent event) {
if (event.getSource().equals(start)) {
if (!recording) {
//if the program isn't recording, then start recording
Graphics g = frame.getGraphics();
record(g);
start.setText("Finish");
recording = true;
System.out.println("recording...");
} else {
//else stop recording
start.setText("record");
recording = false;
System.out.println("done");
}
}
if (event.getSource().equals(close)) {
paused = true;
int ans = JOptionPane.showConfirmDialog(null, "Woah there! You're about to quit the application\nAre you sure you want to procced?", "Caution!", JOptionPane.YES_NO_OPTION);
if (ans == JOptionPane.YES_OPTION) {
System.exit(0);
} else if (ans == JOptionPane.NO_OPTION) {
paused = false;
}
}
}
}
any help is appreciated!
Don't use getGraphics, this is not how custom painting is done.
Your run method may simply be running to fast, consider using a javax.swing.Timer instead
Toolkit.getDefaultToolkit().getScreenSize() only returns the "default" screen and does not take into consideration split screens
Capturing the screen is a time consuming process and there's not much you can do about reducing it (as it's outside of your control). You "could" setup a series of Threads whose job it was to capture a given section of the desktop. You could also achieve this using SwingWorkers which would make it easier to sync the updates back to the UI...
Take a look at:
Performing Custom Painting
Concurrency in Swing
How to Use Swing Timers
Updated with example
This is a proof of concept only! You should understand what it's trying to do and borrow ideas from it...
You can see the preview window change inside the preview window...kinda freaky...
It tested this on a virtual desktop of 4480x1600.
Basically, it divides the desktop up into a 4x4 grid and starts a Thread for each section. Each thread is responsible for capturing it's own section of the screen.
It also scales that resulting image down and feeds it back to the UI.
I had started with SwingWorkers, but it seems to be hard to be limited to 10 threads. You could reduce the grid size and use SwingWorkers, they tend to be simpler to use and manage then raw Threads.
Each section is given an id, which allows me keep track of what's changed. Technically, you could just add elements to a List, but how do you determine what's new and what's old?
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Robot;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class PreviewDesktop {
public static void main(String[] args) {
new PreviewDesktop();
}
public PreviewDesktop() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel implements Puzzler {
private Rectangle virtualBounds;
private double scale;
private Map<Integer, PuzzlePiece> pieces;
public TestPane() {
virtualBounds = getVirtualBounds();
int columns = 4;
int rows = 4;
pieces = new HashMap<>(columns * rows);
int columnWidth = Math.round(virtualBounds.width / (float) columns);
int rowHeight = Math.round(virtualBounds.height / (float) rows);
int id = 0;
for (int row = 0; row < rows; row++) {
int y = virtualBounds.y + (row * rowHeight);
for (int column = 0; column < columns; column++) {
int x = virtualBounds.x + (column * columnWidth);
Rectangle bounds = new Rectangle(x, y, columnWidth, rowHeight);
GrabberWorker worker = new GrabberWorker(id, this, bounds);
System.out.println(id);
id++;
startThread(worker);
}
}
}
#Override
public double getScale() {
return scale;
}
#Override
public void invalidate() {
super.invalidate();
scale = getScaleFactorToFit(virtualBounds.getSize(), getSize());
}
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
for (Integer id : pieces.keySet()) {
PuzzlePiece piece = pieces.get(id);
Rectangle bounds = piece.getBounds();
BufferedImage img = piece.getImage();
g2d.drawImage(img, bounds.x, bounds.y, this);
// If you want to see each sections bounds, uncomment below...
//g2d.draw(bounds);
}
g2d.dispose();
}
#Override
public void setPiece(int id, PuzzlePiece piece) {
pieces.put(id, piece);
repaint();
}
protected void startThread(GrabberWorker worker) {
Thread thread = new Thread(worker);
thread.setDaemon(true);
thread.start();
}
}
public class PuzzlePiece {
private final Rectangle bounds;
private final BufferedImage img;
public PuzzlePiece(Rectangle bounds, BufferedImage img) {
this.bounds = bounds;
this.img = img;
}
public Rectangle getBounds() {
return bounds;
}
public BufferedImage getImage() {
return img;
}
}
public interface Puzzler {
public void setPiece(int id, PuzzlePiece piece);
public double getScale();
}
public class GrabberWorker implements Runnable {
private Rectangle bounds;
private Puzzler puzzler;
private int id;
private volatile PuzzlePiece parked;
private ReentrantLock lckParked;
public GrabberWorker(int id, Puzzler puzzler, Rectangle bounds) {
this.id = id;
this.bounds = bounds;
this.puzzler = puzzler;
lckParked = new ReentrantLock();
}
protected void process(PuzzlePiece piece) {
// puzzler.setPiece(bounds, chunks.get(chunks.size() - 1));
puzzler.setPiece(id, piece);
}
protected void publish(PuzzlePiece piece) {
lckParked.lock();
try {
parked = piece;
} finally {
lckParked.unlock();
}
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
lckParked.lock();
try {
process(parked);
} finally {
lckParked.unlock();
}
}
});
}
#Override
public void run() {
try {
Robot bot = new Robot();
while (true) {
BufferedImage img = bot.createScreenCapture(bounds);
double scale = puzzler.getScale();
Rectangle scaled = new Rectangle(bounds);
scaled.x *= scale;
scaled.y *= scale;
scaled.width *= scale;
scaled.height *= scale;
BufferedImage imgScaled = getScaledInstance(img, scale);
publish(new PuzzlePiece(scaled, imgScaled));
Thread.sleep(500);
}
} catch (AWTException | InterruptedException exp) {
exp.printStackTrace();
}
}
}
public static Rectangle getVirtualBounds() {
Rectangle bounds = new Rectangle(0, 0, 0, 0);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice lstGDs[] = ge.getScreenDevices();
for (GraphicsDevice gd : lstGDs) {
bounds.add(gd.getDefaultConfiguration().getBounds());
}
return bounds;
}
public static double getScaleFactorToFit(Dimension original, Dimension toFit) {
double dScale = 1d;
if (original != null && toFit != null) {
double dScaleWidth = getScaleFactor(original.width, toFit.width);
double dScaleHeight = getScaleFactor(original.height, toFit.height);
dScale = Math.min(dScaleHeight, dScaleWidth);
}
return dScale;
}
public static double getScaleFactor(int iMasterSize, int iTargetSize) {
double dScale = (double) iTargetSize / (double) iMasterSize;
return dScale;
}
public static BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor) {
return getScaledInstance(img, dScaleFactor, RenderingHints.VALUE_INTERPOLATION_BILINEAR, true);
}
protected static BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor, Object hint, boolean bHighQuality) {
BufferedImage imgScale = img;
int iImageWidth = (int) Math.round(img.getWidth() * dScaleFactor);
int iImageHeight = (int) Math.round(img.getHeight() * dScaleFactor);
// System.out.println("Scale Size = " + iImageWidth + "x" + iImageHeight);
if (dScaleFactor <= 1.0d) {
imgScale = getScaledDownInstance(img, iImageWidth, iImageHeight, hint, bHighQuality);
} else {
imgScale = getScaledUpInstance(img, iImageWidth, iImageHeight, hint, bHighQuality);
}
return imgScale;
}
protected static BufferedImage getScaledDownInstance(BufferedImage img,
int targetWidth,
int targetHeight,
Object hint,
boolean higherQuality) {
int type = (img.getTransparency() == Transparency.OPAQUE)
? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage ret = (BufferedImage) img;
if (targetHeight > 0 || targetWidth > 0) {
int w, h;
if (higherQuality) {
// Use multi-step technique: start with original size, then
// scale down in multiple passes with drawImage()
// until the target size is reached
w = img.getWidth();
h = img.getHeight();
} else {
// Use one-step technique: scale directly from original
// size to target size with a single drawImage() call
w = targetWidth;
h = targetHeight;
}
do {
if (higherQuality && w > targetWidth) {
w /= 2;
if (w < targetWidth) {
w = targetWidth;
}
}
if (higherQuality && h > targetHeight) {
h /= 2;
if (h < targetHeight) {
h = targetHeight;
}
}
BufferedImage tmp = new BufferedImage(Math.max(w, 1), Math.max(h, 1), type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(ret, 0, 0, w, h, null);
g2.dispose();
ret = tmp;
} while (w != targetWidth || h != targetHeight);
} else {
ret = new BufferedImage(1, 1, type);
}
return ret;
}
protected static BufferedImage getScaledUpInstance(BufferedImage img,
int targetWidth,
int targetHeight,
Object hint,
boolean higherQuality) {
int type = BufferedImage.TYPE_INT_ARGB;
BufferedImage ret = (BufferedImage) img;
int w, h;
if (higherQuality) {
w = img.getWidth();
h = img.getHeight();
} else {
w = targetWidth;
h = targetHeight;
}
do {
if (higherQuality && w < targetWidth) {
w *= 2;
if (w > targetWidth) {
w = targetWidth;
}
}
if (higherQuality && h < targetHeight) {
h *= 2;
if (h > targetHeight) {
h = targetHeight;
}
}
BufferedImage tmp = new BufferedImage(w, h, type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(ret, 0, 0, w, h, null);
g2.dispose();
ret = tmp;
tmp = null;
} while (w != targetWidth || h != targetHeight);
return ret;
}
}
Now, if you're feeling really adventurous, you could update this idea so that if the underlying image for a section didn't change and the scale didn't change, it didn't send that to the UI, which might help reduce some of the overhead ... and no, I don't have code to do that ;)

How to obtain new height and width of resized image?

i am trying to save new resized image but i exactly don't have any idea to get the new height & width or axis of image.
if anyone knows it then i will be so thankful.
my code to resize image or to scale image is as follows :
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ImageViewer {
public static void main(String[] args) {
new ImageViewer();
}
public ImageViewer() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new ViewPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ViewPane extends JPanel {
public ViewPane() {
setLayout(null);
ImagePane imagePane = new ImagePane();
imagePane.setSize(imagePane.getPreferredSize());
imagePane.setLocation(0, 0);
add(imagePane);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public static class ImagePane extends JPanel {
private BufferedImage bg;
private BufferedImage scaled;
public ImagePane() {
try {
bg = ImageIO.read(new File("src.jpg"));
scaled = getScaledInstanceToFit(bg, new Dimension(100, 100));
} catch (IOException ex) {
ex.printStackTrace();
}
setBackground(Color.BLACK);
MouseHandler handler = new MouseHandler();
addMouseListener(handler);
addMouseMotionListener(handler);
}
#Override
public Dimension getPreferredSize() {
return bg == null ? new Dimension(200, 200) : new Dimension(scaled.getWidth(), scaled.getHeight());
}
#Override
public void invalidate() {
super.invalidate();
scaled = getScaledInstanceToFit(bg, getSize());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - scaled.getWidth()) / 2;
int y = (getHeight() - scaled.getHeight()) / 2;
g2d.drawImage(scaled, x, y, this);
g2d.dispose();
}
public enum MouseAction {
Move(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)),
ResizeSouth(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR)),
ResizeNorth(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR)),
ResizeEast(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR)),
ResizeWest(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR)),
ResizeNorthEast(Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR)),
ResizeNorthWest(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR)),
ResizeSouthEast(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR)),
ResizeSouthWest(Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR));
private Cursor cursor;
private MouseAction(Cursor cursor) {
this.cursor = cursor;
}
public Cursor getCursor() {
return cursor;
}
}
public class MouseHandler extends MouseAdapter {
private MouseAction action;
private Point clickPoint;
private Point offset;
private boolean ignoreMoves;
protected void updateAction(MouseEvent e) {
int x = e.getX();
int y = e.getY();
int width = getWidth();
int height = getHeight();
if (x < 10 && y < 10) {
action = MouseAction.ResizeNorthWest;
} else if (x > width - 10 && y < 10) {
action = MouseAction.ResizeNorthWest;
} else if (y < 10) {
action = MouseAction.ResizeNorth;
} else if (x < 10 && y > height - 10) {
action = MouseAction.ResizeSouthWest;
} else if (x > width - 10 && y > height - 10) {
action = MouseAction.ResizeSouthEast;
} else if (y > height - 10) {
action = MouseAction.ResizeSouth;
} else if (x < 10) {
action = MouseAction.ResizeWest;
} else if (x > width - 10) {
action = MouseAction.ResizeEast;
} else {
action = MouseAction.Move;
}
setCursor(action.getCursor());
}
#Override
public void mouseMoved(MouseEvent e) {
if (!ignoreMoves) {
updateAction(e);
}
}
#Override
public void mousePressed(MouseEvent e) {
updateAction(e);
ignoreMoves = true;
clickPoint = e.getPoint();
}
#Override
public void mouseReleased(MouseEvent e) {
clickPoint = null;
ignoreMoves = false;
}
#Override
public void mouseDragged(MouseEvent e) {
switch (action) {
case Move: {
Point p = e.getPoint();
p.x -= clickPoint.x;
p.y -= clickPoint.y;
p = SwingUtilities.convertPoint(ImagePane.this, p, getParent());
setLocation(p);
}
break;
case ResizeWest: {
Point p = e.getPoint();
int xDelta = p.x - clickPoint.x;
int width = getWidth() - xDelta;
int x = getX() + xDelta;
setSize(width, getHeight());
setLocation(x, getY());
revalidate();
}
break;
case ResizeEast: {
Point p = e.getPoint();
int xDelta = p.x - clickPoint.x;
int width = getWidth() + xDelta;
setSize(width, getHeight());
revalidate();
clickPoint = p;
}
break;
case ResizeNorth: {
Point p = e.getPoint();
int yDelta = p.y - clickPoint.y;
int height = getHeight() - yDelta;
int y = getY() + yDelta;
setSize(getWidth(), height);
setLocation(getX(), y);
revalidate();
}
break;
case ResizeSouth: {
Point p = e.getPoint();
int yDelta = p.y - clickPoint.y;
int height = getHeight() + yDelta;
setSize(getWidth(), height);
revalidate();
clickPoint = p;
}
break;
}
}
#Override
public void mouseExited(MouseEvent e) {
}
}
}
public static BufferedImage getScaledInstanceToFit(BufferedImage img, Dimension size) {
double scaleFactor = getScaleFactorToFit(img, size);
return getScaledInstance(img, scaleFactor);
}
public static BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor) {
BufferedImage imgBuffer = null;
imgBuffer = getScaledInstance(img, dScaleFactor, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
return imgBuffer;
}
protected static BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor, Object hint) {
BufferedImage imgScale = img;
int iImageWidth = (int) Math.round(img.getWidth() * dScaleFactor);
int iImageHeight = (int) Math.round(img.getHeight() * dScaleFactor);
if (dScaleFactor <= 1.0d) {
imgScale = getScaledDownInstance(img, iImageWidth, iImageHeight, hint);
} else {
imgScale = getScaledUpInstance(img, iImageWidth, iImageHeight, hint);
}
return imgScale;
}
protected static BufferedImage getScaledDownInstance(BufferedImage img,
int targetWidth,
int targetHeight,
Object hint) {
// System.out.println("Scale down...");
int type = (img.getTransparency() == Transparency.OPAQUE)
? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage ret = (BufferedImage) img;
if (targetHeight > 0 || targetWidth > 0) {
int w, h;
// Use multi-step technique: start with original size, then
// scale down in multiple passes with drawImage()
// until the target size is reached
w = img.getWidth();
h = img.getHeight();
do {
if (w > targetWidth) {
w /= 2;
if (w < targetWidth) {
w = targetWidth;
}
}
if (h > targetHeight) {
h /= 2;
if (h < targetHeight) {
h = targetHeight;
}
}
BufferedImage tmp = new BufferedImage(Math.max(w, 1), Math.max(h, 1), type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(ret, 0, 0, w, h, null);
g2.dispose();
ret = tmp;
} while (w != targetWidth || h != targetHeight);
} else {
ret = new BufferedImage(1, 1, type);
}
return ret;
}
protected static BufferedImage getScaledUpInstance(BufferedImage img,
int targetWidth,
int targetHeight,
Object hint) {
int type = BufferedImage.TYPE_INT_ARGB;
BufferedImage ret = (BufferedImage) img;
int w, h;
w = img.getWidth();
h = img.getHeight();
do {
if (w < targetWidth) {
w *= 2;
if (w > targetWidth) {
w = targetWidth;
}
}
if (h < targetHeight) {
h *= 2;
if (h > targetHeight) {
h = targetHeight;
}
}
BufferedImage tmp = new BufferedImage(w, h, type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(ret, 0, 0, w, h, null);
g2.dispose();
ret = tmp;
tmp = null;
} while (w != targetWidth || h != targetHeight);
return ret;
}
public static double getScaleFactorToFit(BufferedImage img, Dimension size) {
double dScale = 1;
if (img != null) {
int imageWidth = img.getWidth();
int imageHeight = img.getHeight();
dScale = getScaleFactorToFit(new Dimension(imageWidth, imageHeight), size);
}
return dScale;
}
public static double getScaleFactorToFit(Dimension original, Dimension toFit) {
double dScale = 1d;
if (original != null && toFit != null) {
double dScaleWidth = getScaleFactor(original.width, toFit.width);
double dScaleHeight = getScaleFactor(original.height, toFit.height);
dScale = Math.min(dScaleHeight, dScaleWidth);
}
return dScale;
}
public static double getScaleFactor(int iMasterSize, int iTargetSize) {
double dScale = 1;
if (iMasterSize > iTargetSize) {
dScale = (double) iTargetSize / (double) iMasterSize;
} else {
dScale = (double) iTargetSize / (double) iMasterSize;
}
return dScale;
}
}
i can also move my image easily and also make alteration in size, but now i want to save new image but i have to get first of all its new height and width , if i will get it then i will easily save it.
anyone can assist me ???
Depending on what it's you want to achieve, I would be tempted to add a method to the ImagePane called (something like) save...
public void save(String path, String name) throws IOException {
if (scaled != null) {
name += scaled.getWidth() + "x" + scaled.getHeight();
ImageIO.write(scaled, "png", new File(path + File.separator + name + ".png"));
} else {
throw new NullPointerException("Scaled instance is null");
}
}
Take a look at Writing/Saving an Image
You could also simply pass back a scaled instance based on the ImagePane's state...
public BufferedImage getScaledInstance() {
return getScaledInstanceToFit(bg, getSize());
}
I wouldn't return the scaled object because you don't want people messing with it if you can help it...

Position Image in any Screen Resolution

I have a problem with my program. Every time when I change my screen resolution, my image starts to move out of position. Any suggestions on how to make my image stay in the same location even though I change to any other resolution?
p2 = new JPanel();
p2.setLayout(new FlowLayout());
ImageIcon img2 = new ImageIcon("C:\\Drum\\Invisible4.png");
jbtn2 = new JLabel(img2);
p2.add(jbtn2);
add(jbtn2);
jbtn2.setSize(jbtn2.getPreferredSize());
jbtn2.setLocation(140, 380);
I prefer to always try and work within boundaries of the framework where I can, it makes life generally easier in the long run.
Swing has begin designed to work with LayoutManagers, this means that the way that Swing updates it's components and communicates these changes is based on the use of the LayoutManagers (more or less).
The following example uses pieces from Java: maintaining aspect ratio of JPanel background image to scale the images and a PropertionalLayoutManager which is designed to try and scale not only the size, but also the position of the components based on the size of the parent container.
The PropertionalLayoutManager demonstrated here will try and layout the components around the center of the parent container. You can change this, but it looks weird - IMHO
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LayoutManager2;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.WeakHashMap;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Drums {
protected static BufferedImage SYMBOL;
protected static BufferedImage DRUM;
public static void main(String[] args) {
new Drums();
}
public Drums() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new PropertionalLayoutManager(400, 400));
add(new Symbol(), new PropertionalConstraint(0f, 0));
add(new Symbol(), new PropertionalConstraint(0.67f, 0));
add(new Symbol(), new PropertionalConstraint(0f, 0.4675f));
add(new Symbol(), new PropertionalConstraint(0.67f, 0.4675f));
add(new Drum(), new PropertionalConstraint(0.205f, 0.1f));
add(new Drum(), new PropertionalConstraint(0.5f, 0.1f));
add(new Drum(), new PropertionalConstraint(0f, 0.33f));
add(new Drum(), new PropertionalConstraint(0.705f, 0.33f));
}
}
public class PropertionalConstraint {
private float x;
private float y;
public PropertionalConstraint(float x, float y) {
this.x = x;
this.y = y;
}
public float getX() {
return x;
}
public float getY() {
return y;
}
}
public class PropertionalLayoutManager implements LayoutManager2 {
private Map<Component, PropertionalConstraint> constraints;
private Dimension defaultSize;
public PropertionalLayoutManager(int defaultWidth, int defaultHeight) {
constraints = new WeakHashMap<>(25);
defaultSize = new Dimension(defaultWidth, defaultHeight);
}
#Override
public void addLayoutComponent(Component comp, Object constraint) {
if (constraint instanceof PropertionalConstraint) {
constraints.put(comp, ((PropertionalConstraint) constraint));
}
}
#Override
public Dimension maximumLayoutSize(Container target) {
return preferredLayoutSize(target);
}
#Override
public float getLayoutAlignmentX(Container target) {
return 0.5f;
}
#Override
public float getLayoutAlignmentY(Container target) {
return 0.5f;
}
#Override
public void invalidateLayout(Container target) {
}
#Override
public void addLayoutComponent(String name, Component comp) {
}
#Override
public void removeLayoutComponent(Component comp) {
constraints.remove(comp);
}
#Override
public Dimension preferredLayoutSize(Container parent) {
return defaultSize;
}
#Override
public Dimension minimumLayoutSize(Container parent) {
return preferredLayoutSize(parent);
}
#Override
public void layoutContainer(Container parent) {
int width = parent.getWidth();
int height = parent.getHeight();
double dScaleWidth = getScaleFactor(defaultSize.width, width);
double dScaleHeight = getScaleFactor(defaultSize.height, height);
double scaleSize = Math.min(dScaleHeight, dScaleWidth);
int minRange = Math.min(width, height);
if (width > 0 && height > 0) {
int maxY = 0;
int maxX = 0;
for (Component comp : parent.getComponents()) {
PropertionalConstraint p = constraints.get(comp);
if (p != null) {
Dimension prefSize = comp.getPreferredSize();
prefSize.width *= scaleSize;
prefSize.height *= scaleSize;
int x = Math.round(minRange * p.getX());
int y = Math.round(minRange * p.getY());
comp.setBounds(x, y, prefSize.width, prefSize.height);
maxX = Math.max(maxX, x + prefSize.width);
maxY = Math.max(maxY, y + prefSize.height);
} else {
comp.setBounds(0, 0, 0, 0);
}
}
for (Component comp : parent.getComponents()) {
System.out.println("maxX = " + maxX);
System.out.println("maxY = " + maxY);
if (comp.getWidth() > 0 && comp.getHeight() > 0) {
int x = ((width - maxX) / 2) + comp.getX();
int y = ((height - maxY) / 2) + comp.getY();
comp.setLocation(x, y);
}
}
} else {
for (Component comp : parent.getComponents()) {
comp.setBounds(0, 0, 0, 0);
}
}
}
}
public abstract class AbstractKitPiecePane extends JPanel {
private BufferedImage scaled;
public AbstractKitPiecePane() {
setOpaque(false);
}
public abstract BufferedImage getKitImage();
#Override
public Dimension getPreferredSize() {
return new Dimension(getKitImage().getWidth(), getKitImage().getHeight());
}
#Override
public void invalidate() {
super.invalidate();
if (getWidth() > 0 && getHeight() > 0) {
scaled = getScaledInstanceToFit(getKitImage(), getSize());
} else {
scaled = null;
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (scaled != null) {
int x = (getWidth() - scaled.getWidth()) / 2;
int y = (getHeight() - scaled.getHeight()) / 2;
g.drawImage(scaled, x, y, this);
}
}
}
public class Drum extends AbstractKitPiecePane {
#Override
public BufferedImage getKitImage() {
return DRUM;
}
}
public class Symbol extends AbstractKitPiecePane {
#Override
public BufferedImage getKitImage() {
return SYMBOL;
}
}
protected static BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor) {
BufferedImage imgScale = img;
int iImageWidth = (int) Math.round(img.getWidth() * dScaleFactor);
int iImageHeight = (int) Math.round(img.getHeight() * dScaleFactor);
if (dScaleFactor <= 1.0d) {
imgScale = getScaledDownInstance(img, iImageWidth, iImageHeight, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
} else {
imgScale = getScaledUpInstance(img, iImageWidth, iImageHeight, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
}
return imgScale;
}
protected static BufferedImage getScaledDownInstance(BufferedImage img,
int targetWidth,
int targetHeight,
Object hint) {
// System.out.println("Scale down...");
int type = (img.getTransparency() == Transparency.OPAQUE)
? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage ret = (BufferedImage) img;
if (targetHeight > 0 || targetWidth > 0) {
int w, h;
w = img.getWidth();
h = img.getHeight();
do {
if (w > targetWidth) {
w /= 2;
if (w < targetWidth) {
w = targetWidth;
}
}
if (h > targetHeight) {
h /= 2;
if (h < targetHeight) {
h = targetHeight;
}
}
BufferedImage tmp = new BufferedImage(Math.max(w, 1), Math.max(h, 1), type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(ret, 0, 0, w, h, null);
g2.dispose();
ret = tmp;
} while (w != targetWidth || h != targetHeight);
} else {
ret = new BufferedImage(1, 1, type);
}
return ret;
}
protected static BufferedImage getScaledUpInstance(BufferedImage img,
int targetWidth,
int targetHeight,
Object hint) {
int type = BufferedImage.TYPE_INT_ARGB;
BufferedImage ret = (BufferedImage) img;
int w, h;
w = img.getWidth();
h = img.getHeight();
do {
if (w < targetWidth) {
w *= 2;
if (w > targetWidth) {
w = targetWidth;
}
}
if (h < targetHeight) {
h *= 2;
if (h > targetHeight) {
h = targetHeight;
}
}
BufferedImage tmp = new BufferedImage(w, h, type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(ret, 0, 0, w, h, null);
g2.dispose();
ret = tmp;
tmp = null;
} while (w != targetWidth || h != targetHeight);
return ret;
}
public static BufferedImage getScaledInstanceToFit(BufferedImage img, Dimension size) {
double scaleFactor = getScaleFactorToFit(img, size);
return getScaledInstance(img, scaleFactor);
}
public static double getScaleFactorToFit(BufferedImage img, Dimension size) {
double dScale = 1;
if (img != null) {
int imageWidth = img.getWidth();
int imageHeight = img.getHeight();
dScale = getScaleFactorToFit(new Dimension(imageWidth, imageHeight), size);
}
return dScale;
}
public static double getScaleFactorToFit(Dimension original, Dimension toFit) {
double dScale = 1d;
if (original != null && toFit != null) {
double dScaleWidth = getScaleFactor(original.width, toFit.width);
double dScaleHeight = getScaleFactor(original.height, toFit.height);
dScale = Math.min(dScaleHeight, dScaleWidth);
}
return dScale;
}
public static double getScaleFactor(int iMasterSize, int iTargetSize) {
double dScale = 1;
if (iMasterSize > iTargetSize) {
dScale = (double) iTargetSize / (double) iMasterSize;
} else {
dScale = (double) iTargetSize / (double) iMasterSize;
}
return dScale;
}
static {
try {
SYMBOL = ImageIO.read(new File("Symbol.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
try {
DRUM = ImageIO.read(new File("Drum.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
And the images used within the program, for your enjoyment. They live in the same directory the program is run from
create a percentage/ratio of the "normal" screen size to what it currently is and multiply that by the pos. Example if the screen size you are working with was 400x600
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double width = screenSize.getWidth();
double height = screenSize.getHeight();
double widthRat = width/600
double heightRat = height/400
then
jbtn2.setLocation(140*widthRat, 380*heightRat);
that way say the screen size was doubled to 1200x800 widthRat would = 2 and double the position. This is kind of a sloppy example but gives the idea
I prefer to use Absolute layout. And here are the codes which should work for you.
Toolkit toolkit=Toolkit.getDefaultToolkit();
JPanel1.setSize(toolkit.getScreenSize().width, toolkit.getScreenSize().height);
int w=toolkit.getScreenSize().width;
int h=toolkit.getScreenSize().height;
JPanel1.setBounds(0, 0, w, h);
This code will fetch the current resolution of your computer...

Categories