I'm creating a simple java program to load a image and zoom in/out the image.
So far I have been able load the picture and zoom it. But when drawing the zoomed out image I can still see the previous image on the JPanel.
Code for loading the image
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileFilter(new FileNameExtensionFilter("Images(jpg,png,gif)", "jpg","png","gif"));
int opt = fileChooser.showOpenDialog(this);
if(opt == JFileChooser.APPROVE_OPTION){
String filePath = fileChooser.getSelectedFile().getAbsolutePath();
try {
bufImage = ImageIO.read(fileChooser.getSelectedFile());
} catch (IOException ex) {
Logger.getLogger(ImageZoom.class.getName()).log(Level.SEVERE, null, ex);
}
image = new ImageIcon(filePath);
imgWidth = image.getIconWidth();
imgHeight = image.getIconHeight();
imagePanel.getGraphics().drawImage(image.getImage(), 0, 100, image.getIconWidth(), image.getIconHeight(), imagePanel);
}
Code for zooming in
double scale_factor = 1.5;
imagePanel.getGraphics().drawImage(image.getImage(), 0, 100, (int)(imgWidth*=scale_factor), (int)(imgHeight*=scale_factor), imagePanel);
Code for zooming out
double scale_factor = 0.5;
imagePanel.getGraphics().drawImage(image.getImage(), 0, 100, (int)(imgWidth*=scale_factor), (int)(imgHeight*=scale_factor), imagePanel);
Can some one please suggest a way to only have the resized image on the panel?
This is how zooming out looks like. same problem occurs when opening a new picture.
I tried repainting the panel but then everything vanishes.
That's because imagePanel.getGraphics() isn't how custom painting works in Swing. Instead, create a custom class which extends from something like JPanel and override it's paintComponent method, painting your scaled image there (making sure to call super.paintComponent first)
See Painting in AWT and Swing and Performing Custom Painting for more details
For example:
zoom using mouse and graphics
Java image zooming japplet
Jpanel resize on repaint
Related
I'm working on an application which allows a used to place controls, move, resize, etc. But I'm trying to add icon images to a button control. When placed and instanced, it resizes the icon image per the code below.
But when I resize the control using user features and it calls this routing again, it fails to resize the image and it remains the original icon size. I've tried using "this.", passing the control to itself, I've done prints to ensure it's seeing the new size and width... what I am missing?
Also, when I create a 2nd control (or 3rd, etc), it uses the 1st image's initial size.
Thanks!
protected void sizeIcon () {
try {
File f2 = new File("media\\button.gif");
BufferedImage inputImage = ImageIO.read(f2);
BufferedImage img = new BufferedImage(this.getWidth(), this.getHeight(), inputImage.getType());
Graphics2D g = img.createGraphics();
g.drawImage(inputImage, 7, 0, this.getWidth(), this.getHeight(), null);
ImageIO.write(img, "gif", new File("test.gif"));
this.setIcon(new ImageIcon("test.gif"));
g.dispose();
} catch(Exception e) {System.out.println(e);}
Sorry, got it, appears the old file was not being replaces.
-MH
I have a program that has multiple layers, in the bottom layer I have a JPanel that I have put a background image on. On top of this I have a JLayeredPane that has some draggable components. My problem is that when the user have uploaded a background image the draggable components are really lagging, my guess is that it's because of that swing is repainting the background image al the time when dragging. My question is if its anyway to make sure the image is not repainting all the time?
My code where I paint the image looks like this:
if (this.getLoadedBackgroundImage() != null) {
try {
BufferedImage bufferedImage = ImageIO.read(this.getLoadedBackgroundImage());
Image bImage = bufferedImage.getScaledInstance(this.getWidth() - 5 - jPanel6.getWidth() -5, this.getHeight() - jPanel2.getHeight() - jPanel3.getHeight() - tabPanel.getHeight(), Image.SCALE_FAST);
graphics2d.drawImage(bImage, 5, jPanel2.getHeight() + tabPanel.getHeight()+5, null);
} catch (IOException ex) {
Logger.getLogger(MainViewLayeredPane.class.getName()).log(Level.SEVERE, null, ex);
}
}
Don't load or resize the image the paintComponent method, these are expensive operations, instead, pre-cache it and only paint the cached version
I need a function/method that can mold(crop and resize) an imported (.png format) image into a circle of exact 150x150 pixels and it should keep transparency. I have searched all over internet, also I have my own code but I think its completely useless. I need this function for a code I am using to make GUI of a social-media app database.
private ImageIcon logo = new ImageIcon(getClass().getResource("/test/test200x200.png"));
toCircle(logo);
I need the code for the following function:
public ImageIcon toCircle(ImageIcon icon)
{
//code
return icon;
}
This function should convert this picture:
To this:
Create a new transparent image
Get a Graphics object from the image.
Set a clip for the graphics object.
Paint the PNG format image.
See also this answer that uses a clipped region.
An alternative approach, that might be more straight-forward to implement for this use case, is:
Create a transparent BufferedImage the size of your icon
Create Graphics2D from image, set hints for antialias
Fill a circle the size of your background circle
Draw the image on top of your circle, using AlphaComposite.SrcIn
Something like:
public Icon toCircle(ImageIcon logo) {
BufferedImage image = new BufferedImage(150, 150); // Assuming logo 150x150
Graphics2D g = image.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.fillOval(1, 1, 148, 148); // Leaving some room for antialiasing if needed
g.setComposite(AlphaComposite.SrcIn);
g.drawImage(logo.getImage(), 0, 0, null);
g.dispose();
return new ImageIcon(image);
}
I use OpenImaj for a project and I need to display the video in 800*600 to a panel but I must capture images at 1920,1080 when I click a button.
My strategy was initially to capture from my webcam at 1920,1080 and to resize image in a icon of a label contained in my panelVideo.
My problem is that the performance is very low.
Is there an efficient method to resize video according to the size of panelVideo without changing the frame size (that I use for saving the image at 1920,1080)?
Thank you for your answer.
Regards.
final VideoCapture vc = new VideoCapture(1920,1080);
vc.setFPS(10);
final VideoDisplay<MBFImage> display = VideoDisplay.createVideoDisplay(vc, panelVideo);
display.addVideoListener(new VideoDisplayAdapter<MBFImage>()
{
#Override
public void beforeUpdate(final MBFImage frame)
{
//here I create a bufferedImage from the resized frame
BufferedImage img = new BufferedImage(800, 600, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) img.getGraphics();
g.drawImage(ImageUtilities.createBufferedImageForDisplay(frame), 0, 0, 800, 600, null);
//here is the label that I use to display the video
labelVideo.setIcon(new ImageIcon(ImageUtilities.createBufferedImageForDisplay(frame)));
}
});
You can at least remove fixed code like this out of the loop - that is create it only once
//here I create a bufferedImage from the resized frame
BufferedImage img = new BufferedImage(800, 600, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) img.getGraphics();
and also have the Icon created once and setImage() as needed. Beyond that I dont know how to convert MBF to BufferedImage thats the pain of using different libraries. g.drawImage() is a good way to draw the scaled image.
See http://openimaj.org/apidocs/org/openimaj/image/processing/resize/package-frame.html for the OpenIMAJ classes that let you resize an MBFImage. You'll have to play and see what is fastest, but in my very quick experiments I found BilinearInterpolation to be better than ResizeProcessor with the default options, however using a different filter in ResizeProcessor might be faster.
Rather than creating a new BufferedImage each frame, you would probably be better off drawing the MBFImage into a Swing component that displays them directly: http://openimaj.org/apidocs/org/openimaj/image/DisplayUtilities.ScalingImageComponent.html or http://openimaj.org/apidocs/org/openimaj/image/DisplayUtilities.ImageComponent.html (note that technically these both convert to BufferedImage behind the scenes, but they only allocate the image once and just redraw into it saving a lot of time).
I need to save a chessboard as a jpeg file. I know how to save a java component into JPEG. But my problem is that I use JButtons as cells and when I try to save the whole chessboard, only the panel is saved. Does anybody know how to save a JComponent WITH ITS CHILD COMPNENTS into JPEG (png etc.) Thank you in advance.
You can print a Component (such as JPanel) to any Graphics object. So, why not use the Graphics object of a BufferedImage and write it to disk.
void takePicture(JPanel panel) {
BufferedImage img = new BufferedImage(panel.getWidth(), panel.getHeight(), BufferedImage.TYPE_INT_RGB);
panel.print(img.getGraphics()); // or: panel.printAll(...);
try {
ImageIO.write(img, "jpg", new File("panel.jpg"));
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
This makes this JPanel
JPanel panel = new JPanel();
panel.add(new JButton("Hello"));
panel.add(new JButton("World"));
Look like this:
updated based on comments, many thanks to #MadProgrammer
Check out Screen Image. It will allow you to create an image of any component in the frame. If you choose to make an image of a panel all the child components are included in the image.
Use Robot class to create a screen capture of your screen.
Use this tutorial for help:
Screen Capture using Robot class
Now for your chessboard, clip the image by calling subImage method of BufferedImage class.
Here's the link on clipping BufferedImage
You can get Dimensions of you JPanel by calling getX(), getY(), getWidth() and getHeight() methods which you can pass into subImage method.
Manipulate the passing value by adding/substracting some value to get desired results.