Is it possible to run a sketch with no background (or any kind of transparency)

edited June 2015 in How To...

I know there is a workaround for this in processing.js with some canvas transparency magic, but what I'm wonder is whether it is possible to achieve something like this when running a sketch on desktop.

Cheers

Answers

  • edited June 2015 Answer ✓

    This is not exactly the transparent window but some hack. So What is happening here? Actually, the code takes the screenshot of the desktop and set it as the background of the window. Since the window is full screen and its background is the screenshot of desktop, it feels like the transparent window but still it is not real hack. Here I am sharing two code. Run both of them and you will see the difference.

            import java.awt.Rectangle;
            import java.awt.Robot;
            import java.awt.AWTException;
    
            PImage screenshot;
            Rectangle dimension;
            Robot robot;
            void setup() {
              size(displayWidth, displayHeight);
              initFrame(); 
              screenshot = createImage(displayWidth, displayHeight, ARGB);
              dimension  = new Rectangle(0, 0, displayWidth, displayHeight);
              try {
                robot = new Robot();
              }
              catch (AWTException cause) {
                println(cause);
                exit();
              }
            }
    
            void initFrame() {
              frame.removeNotify();
              frame.setUndecorated(true);
              frame.addNotify();
            }
            void draw() { 
              background(-1); 
              frame.setLocation(0, 0);
              image(grabScreenshot(screenshot, dimension, robot), 0, 0 );
              line(pmouseX, pmouseY, mouseX, mouseY);
            }
    
    
            static final PImage grabScreenshot(PImage img, Rectangle dim, Robot bot) {
              bot.createScreenCapture(dim).getRGB(0, 0, dim.width, dim.height, img.pixels, 0, dim.width);
              img.updatePixels();
              return img;
            }
    

    but it doesn't clear the screen.

    So here is the another code. It somehow does the trick of clearing the screen (not actually) but still not real hack for transparent window. And the reason why I am saying that is not real because when you run any video in any player in the background any of these codes don't capture the video screens hence the code doesn't update the screenshots. May be I am wrong.

    Okay, I guess the code is updating the screenshot but it is taking the screenshot of the screenshot that has already been set as background so it doesn't feel like it is updating.

    Also note that the code shown below is not my code ....

        /**
             * Author: Tim Pulver
             * Date: 2013
             * Tested with Processing 2.0
             * original code by jungalero (processing.org forum)
             */
    
            // https://gist.github.com/timpulver/3776692
    
            import java.awt.AWTException;
            import java.awt.Robot;
            import java.awt.Rectangle;
            import java.awt.image.BufferedImage;
            import java.awt.GraphicsEnvironment;
            import java.awt.GraphicsDevice;
            import java.awt.DisplayMode;
    
            PImage screenShot;
    
            int W = 400; // width
            int H = 400; // height
            int X = 0; // x-position of the window
            int Y = 0; // y-position of the window
            int XOFF = 0;    // x-offset = distance to the right screen boarder
            int YOFF = 100;  // y-offset = distance to the top screen boarder
    
            void setup() { 
              size(displayWidth, displayHeight);  
              screenShot = getScreen(X, Y, displayWidth, displayHeight);
              initFrame();
            }
    
            /**
             * Removes the windowboarder
             */
            void initFrame() {
              frame.removeNotify();
              frame.setUndecorated(true);
              frame.addNotify();
            }
    
            void draw () {
              //frame.setLocation(X, Y);
              image(screenShot, 0, 0, width, height);
              // draw something to see the window
              fill(0);
              ellipse(mouseX, mouseY, 200, 200);
            }
    
            /**
             * Returns an image of the screen (full)
             */
            PImage getFullscreen() {
              return getScreen(0, 0, displayWidth, displayHeight);
            }
    
            /**
             * Returns an area of the screen (screenshot)
             * @param x Top-Left corner of the area to copy (x)
             * @param y Top Left corner of the area to copy (y)
             * @param w Width of the rectangle
             * @param h Height of the rectangle
             */
            PImage getScreen(int x, int y, int w, int h) {
              GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
              GraphicsDevice[] gs = ge.getScreenDevices();
              DisplayMode mode = gs[0].getDisplayMode();
              Rectangle bounds = new Rectangle(x, y, w, h);
              BufferedImage desktop = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    
              try {
                desktop = new Robot(gs[0]).createScreenCapture(bounds);
              }
              catch(AWTException e) {
                System.err.println("Screen capture failed.");
              }
              return (new PImage(desktop));
            }
    

    Sorry for my bad English.

    I would like to extend this with my question:

    How to take the screenshot of the desktop (background) without the processing window?

  • Answer ✓

    the real hack is this. Here, Jframe is getting transparent but I dont know why the objects drawn on the frame are also getting transparent. I had solved this problem long back but I couldn't remember how.

        import java.awt.*;
        import javax.swing.JFrame;
        import java.awt.AWTException;
        import com.sun.awt.AWTUtilities;
    
        final java.awt.Color fullyTransparent = new java.awt.Color(0, 0, 0, 0);
        void setup() {
          size(400, 400);
          initFrame();
        }
    
        void draw() {
          background(-1); 
          fill(0);
          textSize(24);
          text("Hello", width>>1, 50);
          fill(#F71432);
          noStroke();
          ellipse(mouseX, mouseY, 100, 100);
        }
    
    
        void initFrame() {
          frame.removeNotify();
          frame.setUndecorated(true);
          frame.addNotify();
          frame.setOpacity(0.5f);
          //frame.setBackground(fullyTransparent);
          // AWTUtilities.setWindowOpacity(frame, 0.1f);
        }
    

    Also, if you face any problem while running this code. Try updating your java. I have java 8.

  • Answer ✓

    Okay I modified an old code from some forum ...

    Here it is. Some of the things I couldn't fix it. Probably someone else could help you to fix that.

        import java.awt.*;
        import javax.swing.JFrame;
    
        JFrame topFrame = null;
        PGraphics pg3D;
        int framePosX;
        int framePosY;
        int frameWidth = 500;
        int frameHeight = 500; 
    
        void setup() {
          size(frameWidth, frameHeight);
          framePosX = displayWidth/2;
          framePosY = displayHeight/2;
          pg3D = createGraphics(frameWidth, frameHeight);
        }
        void draw() {
          background(0, 0, 0, 0);
          noFill();
          rect(0, 0, frameWidth, frameHeight);
          pg3D.beginDraw();
          pg3D.background(0, 0, 0, 0);
          pg3D.fill(255, 0, 0); 
          pg3D.ellipse(mouseX, mouseY, 50, 50);
          pg3D.endDraw();
          image(pg3D, 0, 0);
          frame.setVisible(false);
          topFrame.add(this);
        }
    
    
        void init() {
          frame.removeNotify();
          frame.setUndecorated(true); 
          frame.setOpacity(0.0f);
    
          GraphicsConfiguration translucencyCapableGC;
          translucencyCapableGC = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
          topFrame = new JFrame(translucencyCapableGC);
          topFrame.removeNotify();
          topFrame.setUndecorated(true); 
          topFrame.setSize(frameWidth, frameHeight);
          topFrame.setBackground(new Color(0, 0, 0, 0));
          topFrame.setVisible(true); 
          topFrame.addNotify();
          super.init();
          g.format = ARGB;
          g.setPrimary(false);
        }
    
  • Hey blyk!

    I'm sorry for the late reply, I just kind of forgot about posting my question and never checked if there were any answers.

    Anyway, thank you so much for your detailed replies, I'll definitely try and play with your code, cheers!

Sign In or Register to comment.