Проблема создания снимка экрана с окнами с прозрачностью из Java на Linux - PullRequest
0 голосов
/ 18 сентября 2018


Я столкнулся с проблемой получения снимков экрана с Java на Linux с прозрачными окнами.
Проблема в том, что скриншот, сделанный с помощью робота, имеет дело с прозрачными окнами, как будто они были непрозрачными.
Это очень похоже на проблему, изложенную в: Сделать снимок экрана в Java на Linux?

Интересно, есть ли какое-нибудь удовлетворительное решение, чтобы избежать этой проблемы.

Вот код, который я использую для снимков экрана:

protected BufferedImage getScreenShot()
{
    BufferedImage screenShotImage = null;

    try
    {
        screenShotImage = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
    }
    catch( Exception ex )
    {
        ex.printStackTrace();
    }

    return( screenShotImage );
}

Код для получения скриншота следующий (в производном классе JFrame):

public void M_repaint( )
{
    long timeStamp = System.currentTimeMillis();
    if( ( timeStamp - _lastScreenShotTimeStamp ) > 4000 )
    {
        updateAlpha( 0.0f );

        SwingUtilities.invokeLater( new Runnable(){
            @Override
            public void run()
            {
                BufferedImage image = getScreenShot();
                try
                {
                    ImageIO.write(image, "png", new File( "robotScreenshotBefore.png"));
                }
                catch( Exception ex )
                {
                    ex.printStackTrace();
                }

                try
                {
                    String[] cmd = { "./lens.screenshot.sh" };
                    Process script_exec = Runtime.getRuntime().exec(cmd);
                    script_exec.waitFor();
                }
                catch( Exception ex )
                {
                    ex.printStackTrace();
                }

                image = getScreenShot();
                try
                {
                    ImageIO.write(image, "png", new File( "robotScreenshotAfter.png"));
                }
                catch( Exception ex )
                {
                    ex.printStackTrace();
                }
                _lensJPanel.setScreenShotImage( image );
                updateAlpha( 1.0f );
            }
        });

        _lastScreenShotTimeStamp = timeStamp;
    }

    repaint();
}

Сценарий ./lens.screenshot.sh имеет следующее содержимое:

#/bin/bash
rm gnome-screenshot.png
gnome-screenshot --file="gnome-screenshot.png"

Приложение представляет собой увеличительное стекло.
Приложение работает так, что каждый раз, когда окно (линза) меняет свое положение на экране, вызывается функция M_repaint ().
Внутри этой функции есть своего рода таймер, который показывает, что по истечении 4 секунд с последнего снимка экрана создается новый снимок экрана, если внешний вид окна изменился

Ранее для создания снимка экрана JFrame был сделан невидимым, чтобы он не отображался внутри самого снимка экрана.
Но после того, как окно было нарисовано на экране, оно появляется на скриншоте, даже если оно было сделано невидимым ранее.
Я прикрепляю один из наборов снимков экрана, сделанных из приложения, с кодом previus (robotScreenshotBefore.png, gnome-screenshot.png и robotScreenshotAfter.png)

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Наконец, найденное решение состояло в том, чтобы подождать несколько миллисекунд, пока прозрачность не вступит в силу, прежде чем делать снимок экрана, в случае, если ОС не была Windows.

Итак, последняя функция, используемая для рисования, следующая:

public void M_repaint( )
{
    long timeStamp = System.currentTimeMillis();
    if( ( timeStamp - _lastScreenShotTimeStamp ) > 4000 )
    {
        updateAlpha( 0.0f );

        SwingUtilities.invokeLater( new Runnable(){
            @Override
            public void run()
            {
                if( !OSValidator.isWindows() )
                {
                    try
                    {
                        Thread.sleep( 26 );     // if mac or linux (and may be others), give enough time for transparency to take effect.
                    }
                    catch( Exception ex )
                    {
                        ex.printStackTrace();
                    }
                }

                BufferedImage image = getScreenShot();

                _lensJPanel.setScreenShotImage( image );
                updateAlpha( 1.0f );
            }
        });

        _lastScreenShotTimeStamp = timeStamp;
    }

    repaint();
}
0 голосов
/ 18 сентября 2018

Я обновил информацию по этому вопросу, и я также приложу скриншоты, сделанные с компьютера с Linux

Как мы видим на первом снимке экрана (тот, который происходит в обычном исполнении), показано только что сделанное окно прозрачным.
На следующих двух снимках экрана показано окно, которое было правильно сделано невидимым (первое из них взято непосредственно из Linux, а последнее - с помощью Robot после вызова средства создания снимков экрана gnome)

Проблема в том, что приложение не может ждать так много времени, прежде чем сделать снимок экрана, так как это время ожидания отображается как мерцающее раздражение.

robotScreenshotBefore.png
robotScreenshotBefore.png

гном-screenshot.png
gnome-screenshot.png

robotScreenshotAfter.png
robotScreenshotAfter.png

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...