Simple bufferedimage flickering when calling repaint - java

I'm trying to create a webcam view with openCV but when I repaint the saved image it flickers and the images look half gray sometimes.
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class Panel extends JPanel {
BufferedImage img;
public Panel() {
super(true);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
try {
img = ImageIO.read(new File("webcam.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
g.drawImage(img, 0, 0, 640, 480, this);
repaint();
}
}

Don't read your image in your paintComponent() method. Read the image in your constructor.
Also, don't call repaint() from your paintComponent() method. If you need to continuously redraw, use a Thread or a Timer.
Edit: this might need some tweaking, but it's the basic approach I'm talking about:
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class Panel extends JPanel implements Runnable{
BufferedImage img;
public Panel() {
super(true);
new Thread(this).start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if(img != null){
synchronized(this){
g.drawImage(img, 0, 0, 640, 480, this);
}
}
}
public void run(){
while(true){
try {
synchronized(this){
img = ImageIO.read(new File("webcam.jpg"));
}
} catch (IOException e) {
e.printStackTrace();
}
repaint();
try {
Thread.sleep((long) (1000.0/30));
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

Related

Java - How to move object up and down using KeyListener?

I am making a program where the user can use the arroy keys on the keyboard to move through a maze. I am able to get the droid object to move from left to right just fine; but I cannot do the same for moving up or down. When I try to move it in those directions nothing happens at all which I am not understanding. What am I doing wrong? Here is the code :
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class Droid2 extends JPanel
{
int x=10, y=200;
ImageIcon icon = new ImageIcon("robot.jpg");
public Droid2()
{
addKeyListener (new DotsListener());
setFocusable(true);
setPreferredSize(new Dimension(850, 600));
}
public void paintComponent(Graphics page)
{
super.paintComponent(page);
File input = new File("maze.png");
Image img = new ImageIcon("maze.png").getImage();
Image img2 = new ImageIcon("robot.png").getImage();
BufferedImage bufferedImage;
try {
bufferedImage = ImageIO.read(input);
Color c=new Color(bufferedImage.getRGB(x, y));// & 255;int d=(bufferedImage.getRGB(x, y)<<16)&0xFF;
System.out.println("Red:"+c.getRed()+",\t Green:"+c.getGreen()+",\t Blue:"+c.getBlue());
if(c.getBlue()<255)
y-=10;
} catch (IOException e) {
e.printStackTrace();
}
page.drawImage(img, 0, 0, null);
page.drawImage(img2, x, 260, null);
System.out.println();
}
private class DotsListener implements KeyListener
{
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_RIGHT)
x+=10;
else if(e.getKeyCode()==KeyEvent.VK_DOWN)
y+=10;
else if(e.getKeyCode() ==KeyEvent.VK_LEFT)
x-=10;
else if(e.getKeyCode() ==KeyEvent.VK_UP)
y-=10;
repaint();
}
#Override
public void keyReleased(KeyEvent e) {
}
}
}
`
Probably because you are not using the y variable to draw the image, instead you just use a hard-coded 260.

Print screen without JFrame

I want to take a print screen of what is behind the JFrame, without the JFrame itself. The way I tried was to close the window, wait for a while so it fully closes, then take the print screen and then open it again. The current method is not good for what I need since I need to do it more frequently and waiting for the window to close is too much time. Also, I don't want to close the window for that.
Here is my current code:
public class Offscreen {
private static BufferedImage img;
public static void main(String[] main)
throws AWTException, InterruptedException {
JFrame frame = new JFrame() {
#Override
public void paint(Graphics g) {
if (img != null)
// draw print screen
g.drawImage(img, 0, 0, null);
}
};
frame.setSize(500, 500);
frame.setLocation(700, 0);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setVisible(false);
Thread.sleep(200);
// take the picture
Robot r = new Robot();
img = r.createScreenCapture(frame.getBounds());
// show the source again
frame.setVisible(true);
// print on destiny
frame.repaint();
}
}
"Assuming" you only want to capture the area behind the active frame (and as you say, without the frame), then something like..
import java.awt.AWTException;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Robot;
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.lang.reflect.InvocationTargetException;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class PrintScreen01 {
public static void main(String[] args) {
new PrintScreen01();
}
private Timer timer;
public PrintScreen01() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
final PrintPane printPane = new PrintPane();
final JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(printPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.addComponentListener(new ComponentAdapter() {
#Override
public void componentMoved(ComponentEvent e) {
timer.restart();
}
#Override
public void componentResized(ComponentEvent e) {
timer.restart();
}
});
timer = new Timer(250, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (frame.isVisible()) {
takeSnapShot(frame, printPane);
}
}
});
timer.setRepeats(false);
frame.setVisible(true);
// takeSnapShot(frame, printPane);
}
});
}
public void takeSnapShot(JFrame frame, PrintPane pane) {
Rectangle bounds = new Rectangle(pane.getLocationOnScreen(), pane.getSize());
frame.setVisible(false);
new SnapShotWorker(frame, pane, bounds).execute();
}
public class SnapShotWorker extends SwingWorker<BufferedImage, BufferedImage> {
private JFrame frame;
private PrintPane pane;
private Rectangle captureBounds;
public SnapShotWorker(JFrame frame, PrintPane pane, Rectangle bounds) {
this.frame = frame;
this.pane = pane;
captureBounds = bounds;
}
#Override
protected BufferedImage doInBackground() throws Exception {
Thread.sleep(125);
BufferedImage snapShot = null;
try {
Robot bot = new Robot();
snapShot = bot.createScreenCapture(captureBounds);
} catch (AWTException ex) {
ex.printStackTrace();
}
Thread.sleep(125);
return snapShot;
}
#Override
protected void done() {
try {
BufferedImage snapShot = get();
pane.setSnapShot(snapShot);
frame.setVisible(true);
} catch (InterruptedException ex) {
ex.printStackTrace();
} catch (ExecutionException ex) {
ex.printStackTrace();
}
}
}
public class PrintPane extends JPanel {
private BufferedImage background;
public PrintPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
public void setSnapShot(BufferedImage img) {
background = img;
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (background != null) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
g2d.drawImage(background, 0, 0, this);
g2d.dispose();
}
}
}
}
May help...
Now, I had some issues with the timing of Robot, it would seem that part of the operation is threaded in some way, meaning that unless you got the timing of the frame changing between invisible and visible "just" right, you would actually recapture the frame...annoying...
To try and fix this, and reduce the amount of times I tried capturing the screen, I employed a javax.swing.Timer (to reduce the capture attempts) and a SwingWorker to control the actual snapshot process, taking it out of the Event Dispatching Thread, there by ensuring (to some degree) that the window will be invisible.
I also added some additional lag to ensure that the frame was off the screen long enough to prevent it been capture by the snapshot...

Jframe image + textfield

Hi i am trying to make a simple frame displaying an image a textfield and a button, but for some reason the textfield is invisible, since i am quite nooby at java and even more at these graphical things can you help :)
THE CODE
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package solverapplet;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import javax.swing.JTextField;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import sun.misc.BASE64Decoder;
public class AwtImage extends Frame{
Image img;
String base="R0lGODlhDwAPAKECAAAAzMzM/////wAAACwAAAAADwAPAAACIISPeQHsrZ5ModrLlN48CXF8m2iQ3YmmKqVlRtW4MLwWACH+H09wdGltaXplZCBieSBVbGVhZCBTbWFydFNhdmVyIQAAOw==";
/*public static void main(String[] args){
AwtImage ai = new AwtImage();
}*/
public void setbase(String a){
this.base=a;
}
public void refreshimage(){
try {
BASE64Decoder decoder = new BASE64Decoder();
byte[] imgBytes = decoder.decodeBuffer(this.base);
BufferedImage bufImg = ImageIO.read(new ByteArrayInputStream(imgBytes));
//File imgOutFile = new File("newLabel.png");
//ImageIO.write(bufImg, "png", imgOutFile);
img = bufImg;
} catch (IOException ex) {
Logger.getLogger(AwtImage.class.getName()).log(Level.SEVERE, null, ex);
}
}
public AwtImage(){
super("Solve");
try {
BASE64Decoder decoder = new BASE64Decoder();
byte[] imgBytes = decoder.decodeBuffer(this.base);
BufferedImage bufImg = ImageIO.read(new ByteArrayInputStream(imgBytes));
MediaTracker mt = new MediaTracker(this);
img=bufImg;
mt.addImage(img,0);
JTextField textfield= new JTextField("Text field 2", 8);
add(textfield,"South");
setSize(400,400);
//pack();
setVisible(true);
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent we){
dispose();
}
});
} catch (IOException ex) {
Logger.getLogger(AwtImage.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void update(Graphics g){
paint(g);
}
public void paint(Graphics g){
if(img != null)
g.drawImage(img, 100, 100, this);
else
g.clearRect(0, 0, getSize().width, getSize().height);
}
}
It gets instantiated by an other class.
The problem is, you've overridden the paint method without making a call to it's super, meaning that it never gets a chance to paint.
public void paint(Graphics g){
if(img != null)
g.drawImage(img, 100, 100, this);
else
g.clearRect(0, 0, getSize().width, getSize().height);
}
When using java.awt.Frame you will find it difficult to achieve what you. java.swingx.JFrame allows you to override the paintComponent method, which allows you to paint the background of the component, but the java.awt.Frame does not.
You should also avoid mixing light and heavy weight components (I know, it's apparently fixed), but if you can, just avoid it.

How Do I Put JLabel and JTextField on top of Image?

I am trying to create a game where I have a background image and text on top of that in the form of JLabels. How would I go about doing that?
The main reason I'm doing this is so that I can have 2 different text areas with different font sizes. Using g.drawString() will only let you use 1 text size for the whole thing.
Here is my code so far:
package com.cgp.buildtown;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class Intro extends JPanel implements Runnable {
private static final long serialVersionUID = 1L;
private Thread thread;
private BufferedImage bg;
private Font font;
public Intro() {
super();
loadImages();
setFont(loadFont(50f));
}
private Font loadFont(Float f) {
try {
font = Font.createFont(Font.TRUETYPE_FONT, new File("res/komikatext.ttf"));
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(font);
} catch (FontFormatException | IOException e) {
e.printStackTrace();
}
return font.deriveFont(f);
}
private void loadImages() {
try {
bg = ImageIO.read(new File("res/introbg.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
public void addNotify() {
super.addNotify();
thread = new Thread(this);
thread.start();
}
public void run() {
while(true) {
repaint();
}
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.drawImage(bg, 0, 0, null);
}
}
Here is one way.
But of course that is merely a version hacked out of your own code/ specs. For a much better implementation of the same idea, see this Background Panel.
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.net.URL;
import javax.imageio.ImageIO;
public class Intro extends JPanel implements Runnable {
private static final long serialVersionUID = 1L;
private Thread thread;
private BufferedImage bg;
private String html =
"<html><body style='color: yellow;'>" +
"<h1>Game</h1>" +
"<p>Welcome to the Game!";
public Intro() {
super();
loadImages();
setLayout(new BorderLayout());
setBorder(new EmptyBorder(40,40,40,40));
add(new JLabel(html), BorderLayout.NORTH);
add(new JTextField("..enter name"), BorderLayout.SOUTH);
}
private void loadImages() {
try {
URL url = new URL("http://pscode.org/media/stromlo2.jpg");
bg = ImageIO.read(url);
setPreferredSize(new Dimension(bg.getWidth(), bg.getHeight()));
} catch (Exception e) {
e.printStackTrace();
}
}
public void addNotify() {
super.addNotify();
thread = new Thread(this);
thread.start();
}
public void run() {
while(true) {
repaint();
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.drawImage(bg, 0, 0, this);
}
public static void main(String[] args) {
JOptionPane.showMessageDialog(null, new Intro());
}
}
first load the background image then opaque its property then add the other components on it.

How to add event for image

I want to add and event on image. That is, when I click on the image, it should be replaced with another image.
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class RadioButtonLoader extends Canvas{
private static final long serialVersionUID = 1L;
BufferedImage image = null;
public RadioButtonLoader(){
try {
this.image = ImageIO.read(new File("res/rb1.gif"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
public RadioButtonLoader(String checked){
try {
this.image = ImageIO.read(new File("res/rb2.gif"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public void setSize(Dimension d) {
super.setSize(new Dimension(15,22));
}
#Override
public void paint(Graphics g) {
setSize(new Dimension(15,22));
g.drawImage(image, 0, 0, null);
}
}
How can I do it?
Simply you add mouselistner in your image in mouselister onclick method add your code...............
http://www.anyexample.com/programming/java/java_full_screen_image_viewer.xml

Categories

Resources