Results 1 to 18 of 18
  1. #1
    pieter24 is offline Member
    Join Date
    Jun 2016
    Posts
    12
    Rep Power
    0

    Default taking a screenshot for a component without Robot

    Hi,

    I am trying to get a screenshot of my desktop without the use of the Robot.getScreenCapture() method. After some browsing i found that you could create a JFrame with the size of the desktop and
    make it completely transparant. I used this code for this:

    Java Code:
    f= new JFrame("test");
    		
    	
    		f.addWindowListener(new WindowAdapter() {
    		     public void windowClosing(WindowEvent we) { 
    		    	   System.exit(0); 
    		       }
    	});
    	  
    	f.setLocation(0,0);
    	f.setExtendedState( f.getExtendedState()|JFrame.MAXIMIZED_BOTH );
    	
    	GraphicsEnvironment ge = 
            GraphicsEnvironment.getLocalGraphicsEnvironment();
            GraphicsDevice gd = ge.getDefaultScreenDevice();
    
            //If translucent windows aren't supported, exit.
            if (!gd.isWindowTranslucencySupported(TRANSLUCENT)) {
                System.err.println(
                    "Translucency is not supported");
                    System.exit(0);
            }
            
            JFrame.setDefaultLookAndFeelDecorated(true);
            f.setUndecorated(true);
            f.setOpacity(0.00f);
    
            // Display the window.
            f.setVisible(true);
            
            JLabel mainLabel = new JLabel("test");
            mainLabel.setOpaque(false);
            f.getContentPane().add(mainLabel);
    Next i wanted to grab the pixels. On this page (https://tips4java.wordpress.com/2008.../screen-image/) I found the ScreenImage.java class.

    Java Code:
    public static BufferedImage createImage(JComponent component, Rectangle region)
    	{
            //  Make sure the component has a size and has been layed out.
            //  (necessary check for components not added to a realized frame)
    
    		if (! component.isDisplayable())
    		{
    			Dimension d = component.getSize();
    
    			if (d.width == 0 || d.height == 0)
    			{
    				d = component.getPreferredSize();
    				component.setSize( d );
    			}
    
    			layoutComponent( component );
    		}
    
    		BufferedImage image = new BufferedImage(region.width, region.height, BufferedImage.TYPE_INT_RGB);
    		Graphics2D g2d = image.createGraphics();
    
    		//  Paint a background for non-opaque components,
    		//  otherwise the background will be black
    
    		if (! component.isOpaque())
    		{
    			g2d.setColor( component.getBackground() );
    			g2d.fillRect(region.x, region.y, region.width, region.height);
    		}
    
    		g2d.translate(-region.x, -region.y);
    		component.paint( g2d );
    		g2d.dispose();
    		return image;
    	}
    I cant use this method on the jframe ( because a jframe extends from component and not from JComponent), therefore i added the JLabel to th Jframe. Set the opaque to false. And then made this call:

    Java Code:
    try {
    			
    			Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    			Rectangle region = new Rectangle(0, 0, d.width, d.height);
    			BufferedImage screen =  ImageScreen.createImage(mainLabel,  region);
    			
                            // write image to disk
    		        ImageIO.write(screen,"png",new File("C:\\Users\\Gebruiker\\Documents\\screenshot.png"));
    		}
    		catch ( Exception e) {
    			e.printStackTrace();
    		}
    Problem is i get a grey image with the label test printed. So the label is captured. Only it is not tranparant. What am i missing here?

  2. #2
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    6,226
    Rep Power
    13

    Default Re: taking a screenshot for a component without Robot

    I haven't had time to experiment with this or study it in detail. But transparency in images is controlled by the alpha bits (high order 8 bits in a 32 bit pixel). So change this:

    BufferedImage.TYPE_INT_RGB

    to this

    BufferedImge.TYPE_INT_ARGB

    And see if that helps. In the meantime, I will take a closer look at your code.

    Regards,
    Jim
    The JavaTM Tutorials | SSCCE | Java Naming Conventions
    Poor planning on your part does not constitute an emergency on my part

  3. #3
    pieter24 is offline Member
    Join Date
    Jun 2016
    Posts
    12
    Rep Power
    0

    Default Re: taking a screenshot for a component without Robot

    Thanks for your reply. I changed it, as you suggested (without the typo ;) , but no effect :(

  4. #4
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    19,964
    Rep Power
    31

    Default Re: taking a screenshot for a component without Robot

    My thoughts on this without any code to test with: If the program displays a component with transparent holes in it, when the program tries to get the contents of those holes it would get nothing because it hasn't displayed anything there.
    If you don't understand my response, don't ignore it, ask a question.

  5. #5
    pieter24 is offline Member
    Join Date
    Jun 2016
    Posts
    12
    Rep Power
    0

    Default Re: taking a screenshot for a component without Robot

    okay. makes sense. do you have a suggestion how to go about it in a different way? The JFrame is displayed perfectly. Transparency working great. I just need to get the pixels ( color values ) of this JFrame. Without using the robot class.

  6. #6
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    6,226
    Rep Power
    13

    Default Re: taking a screenshot for a component without Robot

    I'm not certain what you are trying to do but your second attempt is still using the robot. If you simply want to overlay the screen with a partially opaque window then try this:

    Java Code:
    public class ScreenHide extends JWindow {
       Dimension     size;
       BufferedImage buf;
    
       public ScreenHide() {
          size = Toolkit.getDefaultToolkit().getScreenSize();
          buf = new BufferedImage(size.width, size.height,
                BufferedImage.TYPE_INT_ARGB);
          setOpacity(.5f);
        
          addMouseListener(new MouseAdapter() {
             public void mouseClicked(MouseEvent me) {
                System.out.println("Exiting");
                System.exit(0);
             }
          });
          setPreferredSize(size);
          setVisible(true);
          pack();
       }
       public static void main(String[] args) {
          ScreenHide sc = new ScreenHide();
       }
    
       public void paint(Graphics g) {
          super.paint(g);
          g.drawImage(buf, 0, 0, null);
       }
    }
    The mouse stuff is just to make it easier to exit (since any ide buttons are likely to be intercepted by the window).

    Regards,
    Jim
    The JavaTM Tutorials | SSCCE | Java Naming Conventions
    Poor planning on your part does not constitute an emergency on my part

  7. #7
    pieter24 is offline Member
    Join Date
    Jun 2016
    Posts
    12
    Rep Power
    0

    Default Re: taking a screenshot for a component without Robot

    Thanks jim. Will try it next. But how does my attempt still use the robot? I dont see any robot methods.


    What i need is a window that is 100% transparant. Covering the entire screen. And then get the pixels inside it.

  8. #8
    pieter24 is offline Member
    Join Date
    Jun 2016
    Posts
    12
    Rep Power
    0

    Default Re: taking a screenshot for a component without Robot

    Just tested your class HideScreen jim. But when i do:

    ScreenHide screenCapture = new ScreenHide();
    BufferedImage snap = screenCapture.buf;
    ImageIO.write(snap,"png",new File("C:\\Users\\Gebruiker\\Documents\\screenshot. png"));

    I still do not get the screen. But a grey area.

  9. #9
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    6,226
    Rep Power
    13

    Default Re: taking a screenshot for a component without Robot

    The code you posted from ScreenImage.java actually uses the Robot class to grab the screen image. Perhaps you didn't use all of Rob's code but
    you need to Robot to grab the desktop image. His code simply optimizes the selection process and lets the individual components write to a buffered image
    when they are painting. But he still relies on Robot for special circumstances. At least, that is my take on it.

    Regards,
    Jim
    The JavaTM Tutorials | SSCCE | Java Naming Conventions
    Poor planning on your part does not constitute an emergency on my part

  10. #10
    pieter24 is offline Member
    Join Date
    Jun 2016
    Posts
    12
    Rep Power
    0

    Default Re: taking a screenshot for a component without Robot

    yes i know. but i did not use that method. only the

    public static BufferedImage createImage(JComponent component, Rectangle region)

    which does not use the robot code if i am correct.

  11. #11
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    19,964
    Rep Power
    31

    Default Re: taking a screenshot for a component without Robot

    Can you post the code you are using so every one is working on the same problem?
    If you don't understand my response, don't ignore it, ask a question.

  12. #12
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    6,226
    Rep Power
    13

    Default Re: taking a screenshot for a component without Robot

    As I said, that just throws a slightly transparent window over the screen. Capturing is simple using Robot.
    try/catch blocks need to be added.

    Java Code:
    public static void main(String[] args) {
          Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
          BufferedImage buf = new Robot().createScreenCapture(new Rectangle(size));
          ImageIO.write(buf, "png", new File(saveFileName));
    }
    Regards,
    Jim
    The JavaTM Tutorials | SSCCE | Java Naming Conventions
    Poor planning on your part does not constitute an emergency on my part

  13. #13
    pieter24 is offline Member
    Join Date
    Jun 2016
    Posts
    12
    Rep Power
    0

    Default Re: taking a screenshot for a component without Robot

    But i dont want to use Robot. That was the whole Idea. I dont think you need to. Here is my complete program so you can run it: ( i converted it so its all in a single class for testing purposes)

    Java Code:
    import java.awt.event.WindowEvent;
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.image.BufferedImage;
    import javax.imageio.ImageIO;
    import java.io.File;
    import static java.awt.GraphicsDevice.WindowTranslucency.*;
    
    
    
    
    public class Run {
    
    	 JFrame f;
         JLabel mainLabel;
    
    	
    	
    	
    	
    	 public static void main(String argv[]) {
    		 
    		 Run run = new Run();
    	
    		 run.f = new JFrame("test");
    			
    			
    		 run.f.addWindowListener(new WindowAdapter() {
    			     public void windowClosing(WindowEvent we) { 
    			    	   System.exit(0); 
    			       }
    		 });
    		  
    		run.f.setLocation(0,0);
    		run.f.setExtendedState( run.f.getExtendedState()|JFrame.MAXIMIZED_BOTH );
    	    //f.setSize(200, 200);
    		
    		GraphicsEnvironment ge = 
    	        GraphicsEnvironment.getLocalGraphicsEnvironment();
    	        GraphicsDevice gd = ge.getDefaultScreenDevice();
    
    	        //If translucent windows aren't supported, exit.
    	        if (!gd.isWindowTranslucencySupported(TRANSLUCENT)) {
    	            System.err.println(
    	                "Translucency is not supported");
    	                System.exit(0);
    	        }
    	        
    	        JFrame.setDefaultLookAndFeelDecorated(true);
    	        run.f.setUndecorated(true);
    	        run.f.setOpacity(0.58f);
    
    	        // Display the window.
    	        
    	        run.mainLabel = new JLabel();
    	        run.mainLabel.setOpaque(true);
    		
    	        run.f.add(run.mainLabel);
    	        run.f.pack();
    	        run.f.setVisible(true);
    	        
    	        
    	
    	        
    	        // now try to make the screen shot
    	        try {
    			
    	        	// wait 2 sec and snap
    	        	Thread.sleep(2000);
    				Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    				Rectangle region = new Rectangle(0, 0, d.width, d.height);
    			
    				BufferedImage screen =  createImage(run.mainLabel,  region);
    				
    
    			   ImageIO.write(screen,"png",new File("C:\\Users\\Gebruiker\\Documents\\screenshot.png"));
    			    System.exit(0);
    			}
    			catch ( Exception e) {
    				e.printStackTrace();
    			}
    	
    	
    	  
    	 }
    	 
    		public static BufferedImage createImage(JComponent component, Rectangle region)
    		{
    	        //  Make sure the component has a size and has been layed out.
    	        //  (necessary check for components not added to a realized frame)
    
    			if (! component.isDisplayable())
    			{
    				Dimension d = component.getSize();
    
    				if (d.width == 0 || d.height == 0)
    				{
    					d = component.getPreferredSize();
    					component.setSize( d );
    				}
    
    				layoutComponent( component );
    			}
    
    			BufferedImage image = new BufferedImage(region.width, region.height, BufferedImage.TYPE_INT_ARGB);
    			Graphics2D g2d = image.createGraphics();
    
    			//  Paint a background for non-opaque components,
    			//  otherwise the background will be black
    
    			if (! component.isOpaque())
    			{
    				g2d.setColor( component.getBackground() );
    				g2d.fillRect(region.x, region.y, region.width, region.height);
    			}
    
    			g2d.translate(-region.x, -region.y);
    			component.paint( g2d );
    			g2d.dispose();
    			return image;
    		}
    		
    		static void layoutComponent(Component component)
    		{
    			synchronized (component.getTreeLock())
    			{
    				component.doLayout();
    
    	    	    if (component instanceof Container)
    	        	{
    	            	for (Component child : ((Container)component).getComponents())
    		            {
    	    	            layoutComponent(child);
    	        	    }
    		        }
    	    	}
    	    }
    }

    The resulting screenshot is a grey rectangle. But i want it be my desktop.
    Last edited by pieter24; 06-24-2016 at 03:14 PM.

  14. #14
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    6,226
    Rep Power
    13

    Default Re: taking a screenshot for a component without Robot

    Good luck then. From where are you getting the screen pixels? They are not part of your application.
    That is to say you are not painting your screen, windows is doing that. As I said before, the program
    you have been modifying was designed to quickly paint your GUI into an image buffer instead of on the
    screen. It can do that because the GUI components are under your control. The screen isn't. If it were
    easy to do I believe the API designers would have done it differently. But I believe they wrote some
    native libraries that interact with the Windows display system to get the screen image. This is all just
    a guess on my part. In any event I am afraid have don't have any more to offer. Hat's off to you
    of you succeed in doing this.

    Regards,
    Jim
    The JavaTM Tutorials | SSCCE | Java Naming Conventions
    Poor planning on your part does not constitute an emergency on my part

  15. #15
    pieter24 is offline Member
    Join Date
    Jun 2016
    Posts
    12
    Rep Power
    0

    Default Re: taking a screenshot for a component without Robot

    Hey Jim,

    See this link: java - Swing: Obtain Image of JFrame - Stack Overflow

    And in another discussion forum ( cant recall where ) someone mentioned that if you made the window transparant you could use it to make
    a screenshot.

  16. #16
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    6,226
    Rep Power
    13

    Default Re: taking a screenshot for a component without Robot

    That link was talking about getting a screen shot of a JFrame. Which is a Swing component you have control over. I thought you
    wanted to get a screen shot of your desktop. One of us is not understanding something.

    And in another discussion forum ( cant recall where ) someone mentioned that if you made the window transparant you could use it to make
    a screenshot.
    What did they mean by screenshot? Part of the desktop? If so, as I said that is rendered by the OS you are using.

    Regards,
    Jim
    The JavaTM Tutorials | SSCCE | Java Naming Conventions
    Poor planning on your part does not constitute an emergency on my part

  17. #17
    pieter24 is offline Member
    Join Date
    Jun 2016
    Posts
    12
    Rep Power
    0

    Default Re: taking a screenshot for a component without Robot

    żeah i need the entire desktop. But the trick was to create a window which covered the entire desktop. Then make it transparant. Then get the pixels from this window. I dont know if this can be done. But the guy making the comment said it was a method people used 10 years ago to make a screenshot ( as a quick hack ) and could probably still be done this today ( his words)

  18. #18
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    6,226
    Rep Power
    13

    Default Re: taking a screenshot for a component without Robot

    I don't believe it is possible the way he described it. There was probably more going on under the hood than he realized.

    Regards,
    Jim
    The JavaTM Tutorials | SSCCE | Java Naming Conventions
    Poor planning on your part does not constitute an emergency on my part

Similar Threads

  1. Taking a screenshot and redisplaying it
    By aprop in forum New To Java
    Replies: 3
    Last Post: 03-03-2012, 09:24 PM
  2. Replies: 2
    Last Post: 05-22-2011, 08:56 AM
  3. Replies: 3
    Last Post: 05-03-2011, 03:24 AM
  4. Capturing a screenshot of a another pc?
    By chyrl in forum Advanced Java
    Replies: 9
    Last Post: 06-08-2010, 05:07 PM
  5. Get screenshot(picture) of own pc
    By shekhar2010 in forum New To Java
    Replies: 5
    Last Post: 01-24-2010, 03:48 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •