I am new to swing. I was trying the game tutorial by wilchit sombat on making of packman. I cannot view the BufferedImage. Here is the code which overrides some methods from the game engine.
package game.packman;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.Game.Engine.Game;
import org.Game.Engine.GameApplication;
public class PackMan extends Game {
public static void main(String args[]) {
GameApplication.start(new PackMan());
}
BufferedImage packman;
public PackMan() {
title = "PACKMAN";
width = height = 400;
try {
packman = ImageIO.read(new File("images/pacmanimg.xcf"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void init() {
// TODO Auto-generated method stub
}
#Override
public void update() {
// TODO Auto-generated method stub
}
#Override
public void draw(Graphics g) {
g.drawImage(packman, 100, 100, null);
}
}
Image I/O has built-in support for GIF, PNG, JPEG, BMP, and WBMP. Image I/O is also extensible so that developers or administrators can "plug-in" support for additional formats. For example, plug-ins for TIFF and JPEG 2000 are separately available.
So, it seems that XCF: native image format of the GIMP image-editing program, is not supported by ImageIO.
Reference:
Reading/Loading an Image
Check size of the image packman after loaing
packman = ImageIO.read(new File("images/pacmanimg.xcf"));
It's 0 width/height if the image is not loaded.
Anyway it's better to place the image in your classpath and use getResourceAsStream() to load it through ImageIO. In opposite case when you pack your code in a jar you need to resolve working with files and relative paths problem.
Related
I have a problem with a task that seemed to be pretty easy. I have to create a program that will show images (.jpg,.png and .gif) consecutively. Images have to be the contents of some files, that is given as an argument to the program. When I have to load the images separately, it works, but the issue occurs when I load them one after another with a sleep between them.
Here is my code:
import javax.swing.SwingUtilities;
public class Main {
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new MyFrame(args[0],Integer.parseInt(args[1]));
//First argument is path to file with images, second - amount of time (in seconds) which every image has to stay on the screen until the next one appears
}
});
}
}
import java.io.File;
import javax.swing.*;
public class MyFrame extends JFrame{
public MyFrame(String path, int time){
super("Obrazki");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
MyPanel panel = new MyPanel();
panel.setVisible(true);
this.add(panel);
pack();
File file = new File(path);
String[] tabs = file.list();
for(int i=0; i<tabs.length; i++)
{
panel.loadImage(path+"\\"+tabs[i]);
this.repaint();
try {
Thread.sleep(time*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import javax.swing.JPanel;
public class MyPanel extends JPanel
{
Image img;
public void loadImage(String s)
{
img = Toolkit.getDefaultToolkit().getImage(s);
MediaTracker tracker = new MediaTracker(this);
tracker.addImage(img, 1);
while(!tracker.checkID(1)) {
try {
tracker.waitForID(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.repaint();
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.drawImage(this.img, 0, 0, this.getSize().width, this.getSize().height, this);
}
}
but the issue is when i load them one after another with sleep time between them.
You are causing the Event Dispatch Thread (EDT) to sleep, which means the GUI can't respond to events or repaint itself. Read the section from the Swing tutorial on Concurrency for more information.
Don't use Thread.sleep() when code is executing on the EDT.
For animation you can:
use a SwingWorker (with Thread.sleep())and publish the Icon you want to paint, or
use a Swing Timer. The tutorial also has a section on How to Use Swing Timers.
I am making program which will show zoomed in picture in scrolled frame and allow user to change single pixels of buffered image. I am trying to add panel with buffered image to scrolledPane but scroll bars wont appear.
Here is my panel:
package biometria1;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class noobPanel extends JPanel implements MouseListener{
private BufferedImage background;
int scale = 8;
noobPanel self;
public noobPanel(File file){
self = this;
try {
background = ImageIO.read(file);
} catch (IOException ex) {
Logger.getLogger(noobPanel.class.getName()).log(Level.SEVERE, null, ex);
}
addMouseListener(this);
}
public BufferedImage getImage(){
return this.background;
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(background, 0, 0, background.getWidth()*8, background.getHeight()*8, 0, 0, background.getWidth(), background.getHeight(), this);
}
#Override
public void mouseClicked(MouseEvent e) {
int x = e.getX()/scale;
int y = e.getY()/scale;
System.out.println("before:"+background.getRGB(x, y));
background.setRGB(x, y, 100);
System.out.println("after:"+background.getRGB(x, y));
self.repaint();
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public void mouseEntered(MouseEvent e) {
// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public void mouseExited(MouseEvent e) {
// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
and thats how i add this panel in frame:
File image = chooser.getSelectedFile();
obraz = new noobPanel(image);
scrollPanel= new JScrollPane(obraz);
// 8 because i scale its 8 times bigger
obraz.setPreferredSize(new Dimension(obraz.getWidth()*8, obraz.getHeight()*8));
self.setSize(860, 640);
self.add(scrollPanel);
self.pack();
self.revalidate();
self.repaint();
Could u tell me what I am doing wrong? Thanks for any advice
You never set the size of your panel (preferred or otherwise). So the new Dimension(width*8, height*8) ist still 0,0.
So you can either do what Andrew Thompson suggested and override getPreferredSize() or just set your preferred size in your panels constructor, probably after loading the image since that's what actually matters?
Oh and why do you define the scale and then not use it? I'm talking about the *8 instead of *scale.
Also: This is a little off topic but why do you keep an extra reference "self" around? Seems like unnecessary overhead... You can call all those methods without the "self." in front of them and even if you couldn't there's already the "this" keyword for that. I mean yeah it's only around 4 bytes or something but it looks odd.
I am working on a computer vision project and somewhere in a process an endless loop happens. It seems that my image data is being corrupted.
In past, I used to save debug results on the disk using this method:
public static boolean saveToPath(String path, BufferedImage image) {
File img = new File(path);
try {
ImageIO.write(image, "png", new File(path));
} catch (IOException ex) {
System.err.println("Failed to save image as '"+path+"'. Error:"+ex);
return false;
}
return true;
}
The problem is that once loops are used and the error is somewhere inbetween, I need to see many images. So basically, I'd like a method that would be defined like this:
/** Displays image on the screen and stops the execution until the window with image is closed.
*
* #param image image to be displayed
*/
public static void printImage(BufferedImage image) {
???
}
And could be called in a loop or any function to show be the actual image, effectively behaving like a break point. Because while multithreading is very good in production code, blocking functions are much better for debugging.
You can code something like this. In this example, the image file has to be in the same directory as the source code.
Here's the image displayed in a dialog. You left click the OK button to continue processing.
If the image is bigger than your screen, scroll bars will appear to let you see the whole image.
In your code, since you already have the Image, you can just copy and paste the displayImage method.
package com.ggl.testing;
import java.awt.Image;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class DisplayImage {
public DisplayImage() {
displayImage(getImage());
}
private Image getImage() {
try {
return ImageIO.read(getClass().getResourceAsStream(
"StockMarket.png"));
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public void displayImage(Image image) {
JLabel label = new JLabel(new ImageIcon(image));
JPanel panel = new JPanel();
panel.add(label);
JScrollPane scrollPane = new JScrollPane(panel);
JOptionPane.showMessageDialog(null, scrollPane);
}
public static void main(String[] args) {
new DisplayImage();
}
}
I am working on a java game and the game works perfectly in eclipse, but when I exported is as a runnable jar file it did not work. Only a black window showed up.
My game has a splash screen which changes to menu screen after few seconds. the splash screen sconsists of an BufferedImage (in jpg) but the menu screen also consists of a Graphics2D writing. Few seconds after running the jar file the writing doesn't show up, so I think image formats and such might not be the issue.
I'm quite confused and frustrated so any help would be appriciated.
It turned out the problem is in my use of Timer, this is my source of the splashscreen
package GameState;
import java.awt.Graphics2D;
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.Timer;
import Main.GamePanel;
public class SplashState extends GameState implements ActionListener{
private BufferedImage image;
private Timer timer;
public SplashState(GameStateManager gsm) {
this.gsm = gsm;
try {
image = ImageIO.read(new File("Resources/Backgrounds/block.jpg"));
timer = new Timer(2000, this);
timer.setRepeats(false);
timer.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void init() {
}
public void update() {
}
public void draw(Graphics2D g) {
g.drawImage(image, (GamePanel.WIDTH-image.getWidth())/2, (GamePanel.HEIGHT-image.getHeight())/2, null);
}
public void keyPressed(int k) {
}
public void keyReleased(int k) {}
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
gsm.setState(GameStateManager.MENUSTATE);
timer.stop();
}
}
I still don't know what's wrong so any help would be appriciated
I've had a similar problem in the past, and it was due to the way Eclipse was packaging the required libraries into the jar. I would bet you have it set to "Extract required libraries into generated jar", and you should set it to "Package required libraries into generated jar". To do this, right click on project -> Export -> Java -> Runnable Jar File. Then click next, and select the radio button for "Package required libraries into generated jar". This should fix your problem.
If you are writing to an image, the image must be outside of the jar file, because you cannot edit a jar file while it is running. If this is the case, you may want to make a folder that contains your jar and the images it will write to.
I have a java swing project I have been working on that involves parsing text data and then displaying graphical representations through local image files. I want the user to be able to copy the images displayed so that they can be pasted into other programs (such as Microsoft Word). It doesn't even need to happen like that, just any way I can make .jpg files copied so the user can paste them elsewhere. There would be a long chain of images, so just copying and pasting one at a time is not a possibility. Please help!
So, I threw this together really quickly and it works just fine for me.
Basically, you should be able to "export" just about any java.awt.Image based image, including BufferedImage
Updated, now with improved stiching...
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class ImageTransfer {
public static void main(String[] args) {
try {
BufferedImage left = ImageIO.read(new File("left"));
BufferedImage right = ImageIO.read(new File("right"));
BufferedImage img = new BufferedImage(
left.getWidth() + right.getWidth(),
Math.max(left.getHeight(), right.getHeight()),
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.drawImage(left, 0, (img.getHeight() - left.getHeight()) / 2, null);
g2d.drawImage(right, left.getWidth(), (img.getHeight() - right.getHeight()) / 2, null);
g2d.dispose();
final Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
cb.setContents(new ImageTransferable(img), new ClipboardOwner() {
#Override
public void lostOwnership(Clipboard clipboard, Transferable contents) {
System.out.println("You Lose");
}
});
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static class ImageTransferable implements Transferable {
private BufferedImage img;
public ImageTransferable(BufferedImage img) {
this.img = img;
}
#Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[]{DataFlavor.imageFlavor};
}
#Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
return DataFlavor.imageFlavor.equals(flavor);
}
#Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
if (!isDataFlavorSupported(flavor)) {
throw new UnsupportedFlavorException(flavor);
}
return img;
}
}
}
Note, while I loaded the image from a file, the image could be created dynamically in memory as well and it should work just fine...
Take a look at Writing/Saving an Image, Reading/Loading an Image and Drag and Drop and Data Transfer for more details