Screen grabber program

balanga

Son of Beastie

Reaction score: 111
Messages: 2,730

Does anyone have a recommendation for a screen grabber program? ie something which will capture part of the screen as an image...
 

Spartrekus

Aspiring Daemon

Reaction score: 138
Messages: 916

Does anyone have a recommendation for a screen grabber program? ie something which will capture part of the screen as an image...
pkg install scrot


export DISPLAY=:0
scrot image.png


man scrot
(check -s )
 

aragats

Daemon

Reaction score: 477
Messages: 1,155

import from graphics/ImageMagick6 (actually there are several packages for ImageMagick, but it doesn't matter which one for your purpose).
For a part of screen:
Code:
import /tmp/screenshot.png
For whole screen:
Code:
import -w root /tmp/screenshot.png
 

Spartrekus

Aspiring Daemon

Reaction score: 138
Messages: 916

import from graphics/ImageMagick6 (actually there are several packages for ImageMagick, but it doesn't matter which one for your purpose).
For a part of screen:
Code:
import /tmp/screenshot.png
For whole screen:
Code:
import -w root /tmp/screenshot.png
I noticed that you like heavy installation. But Imagemagick is bloated.
Better to use something lightweight.

there are many like scrot...

what about just using x11 library itself?
I made once a small application in c that copy the desktop using lib x11 only.
 

aragats

Daemon

Reaction score: 477
Messages: 1,155

I noticed that you like heavy installation. But Imagemagick is bloated.
  1. I don't.
  2. I need ImageMagick for other purposes (to convert between formats).
  3. You can build (or select a different package) with options you need.
 

olli@

Well-Known Member
Developer

Reaction score: 276
Messages: 315

Indeed, ImageMagick is a very useful set of tools for manipulating graphics. I always install it, alongside with the netpbm tools (port graphics/netpbm). They complement each other nicely.

However, for making screenshots I prefer to use the “grab” feature of xv (graphics/xv).
 

Spartrekus

Aspiring Daemon

Reaction score: 138
Messages: 916

The X11 force shall be with You always ;)

Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "x11framegrab.h"
#include <X11/Xlib.h>
#include <X11/X.h>
#include <X11/Xatom.h>
#include <unistd.h>

Display *display = 0;
Screen * screen = 0;
Window rootWindow = 0;
XWindowAttributes xwa;

uint8_t * buffer;
int width, height;

const char * output_formats[MAX_OUTPUT_FORMATS];
int (*output_format_writer[MAX_OUTPUT_FORMATS])( );
int output_format_count;
int quality = -1;


static int handler(Display * d, XErrorEvent *e    )
{
    fprintf( stderr, "FAIL: %p\n", d ) ;
    exit( -5 );
}


int CapScreen()
{
    int lx, ly;
    static int did_set_handler;

    if( !did_set_handler )
    {
        XSetErrorHandler( handler );
    }

    if( !display )
    {
        display = XOpenDisplay( 0 );
           screen = XDefaultScreenOfDisplay(display);
        rootWindow = DefaultRootWindow(display);
        XGetWindowAttributes(display, rootWindow, &xwa);
    }

    width = xwa.width;
    height = xwa.height;

    XImage * m = XGetImage( display, rootWindow, 0, 0, width, height, AllPlanes, XYPixmap);

    if( m->bitmap_pad != 32 )
    {
        fprintf( stderr, "Bad bitmap pad\n" );
        return -1;
    }

    uint8_t * bp = buffer = malloc( width * height * 3 );
    for( ly = 0; ly < height; ly++ )
    {
        for( lx = 0; lx < width; lx++ )
        {
            uint32_t px = XGetPixel( m, lx, ly );
            //(*(pb++)) = (px>>16) | (px&0xff00) | ((px&0xff)<<16);
            (*bp++) = px>>16;
            (*bp++) = px>>8;
            (*bp++) = px;
        }
    }
    XDestroyImage( m );
    return 0;
}



int main( int argc, char ** argv )
{
    int i;
    int showhelp = 0;
    char c;
    const char * outformat = "ppm";
    const char * outfile = 0;
    int rescale = 0;
    outputf = stdout;

    while( (c = getopt( argc, argv, "s:q:o:f:h?" )) != -1 )
    {
        switch( c )
        {
        case 's':
            if( optarg )
            {
                rescale = atoi( optarg );
            }
            else
            {
                rescale = 1;
            }
        case 'q':
            if( optarg )
            {
                quality = atoi( optarg );
            }
            else
            {
                fprintf( stderr, "-q expects parameter.\n" );
            }
            break;
        case 'o':
            outfile = optarg;
            break;
        case 'f':
            outformat = optarg;
            break;
        case '?': case 'h':
        default:
            showhelp = 1;
        }
    }

    if( showhelp || !outfile )
    {
        fprintf( stderr, "x11framegrab - grab x11 frames to files or stdio. Parameters:\n" );
        fprintf( stderr, "  -o [outfile, use - for stdout, REQUIRED field]\n" );
        fprintf( stderr, "  -f [format, default .ppm] available formats are:\n    " );
        for( i = 0; i < output_format_count; i++ )
            fprintf( stderr, "%s%c", output_formats[i], ((i+1)!=output_format_count)?',':'\n' );
        fprintf( stderr, "  -q [quality, if applicable, 1 = bad, 2 = ok, 3 = good]\n" );
        fprintf( stderr, "  -s [rescale quantity, # of times to divide by 2]\n" );
        return -5;
    }
    if( CapScreen() )
    {
        fprintf( stderr, "Fatal error capturing screen.\n" );
        return -1;
    }

    if( strcmp( outfile, "-" ) == 0 )
    {
        outputf = stdout;
    }
    else
    {
        outputf = fopen( outfile, "wb" );
    }

    if( !outputf )
    {
        fprintf( stderr, "Error: Could not open file \"%s\" for writing.\n", outfile );
        return -8;
    }

    int newwidth = width;
    int newheight = height;
    while( rescale > 0 )
    {
        newwidth = (width+1) / 2;
        newheight = (height+1) / 2;
        uint8_t * newbuffer = malloc( newwidth * newheight * 3 );
        int x, y;
        for( y = 0; y < newheight; y++ )
        {
            for( x = 0; x < newwidth; x++ )
            {
                int comp, val;
                for( comp = 0; comp < 3; comp++ )
                {
                    val = 0;
                    val += buffer[((y*2+0)*width+(x*2+0))*3+comp];
                    val += buffer[((y*2+0)*width+(x*2+1))*3+comp];
                    val += buffer[((y*2+1)*width+(x*2+0))*3+comp];
                    val += buffer[((y*2+1)*width+(x*2+1))*3+comp];
                    val = (val+2)>>2; //Prevent darkening bias.
                    newbuffer[(x+y*newwidth)*3+comp] = val;
                }
            }
        }

        width = newwidth;
        height = newheight;
        free( buffer );
        buffer = newbuffer;
        rescale--;
    }


    for( i = 0; i < output_format_count; i++ )
    {
        if( strcmp( outformat, output_formats[i] ) == 0 )
        {
            //Match
            return output_format_writer[i]( );
        }
    }

    fprintf( stderr, "Error: Could not find output format driver: %s\n", outformat );
    return -1;
}
 
  • Thanks
Reactions: dch

aragats

Daemon

Reaction score: 477
Messages: 1,155

Where is x11framegrab.h?
Also, your program grabs the entire screen, what if I need just a region?
 

olli@

Well-Known Member
Developer

Reaction score: 276
Messages: 315

Does anyone have a recommendation for a screen grabber program? ie something which will capture part of the screen as an image...
By the way, there is also x11/xgrab. But chances are that you already have a graphics program or toolset installed that is also capable of doing screen shots (Gimp, ImageMagick, xv, …).
 

Spartrekus

Aspiring Daemon

Reaction score: 138
Messages: 916

likely xv or scrot are the best bet.

clang + Xorg is a nice method, since it offers to have full control (with simple code).
 
Top