You are not logged in.

#1 2011-12-24 09:47:06

topcat-software
Member
Registered: 2011-12-17
Posts: 20
Website

screen-shot tools: root2jpg and root2xpm

Hi folks (new kid in town...)

Saw this sub-board in the forum & spent the next few evenings browsing all the very nifty projects you all have created, some innovative stuff so... I thought I'd add my own contributions to the mix =)

Here are two routines to take screen-shots, the 1st outputs a compressed JPG, & the 2nd a pixmap in XPM format.

But first an example... here's a JPG taken with root2jpg.

These could easily be hard-coded into for instance config.h in dwm, or a script with xbindkeys where either called a modifier and say the print-screen key (XK_Print).

Since I'm not yet running Arch, I can't roll up any packages (any takers?) At any rate, hope you all can use them!

/* 

roo2jpg v0.98 [c]2012 Topcat Software LLC.

http://www.topcat.hypermart.net/index.html

Permission  is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in  the Software without restriction, including without limitation the rights
to  use,  copy,  modify,  merge, publish, distribute, sublicense, and/or sell
copies  of  the  Software,  and  to  permit  persons  to whom the Software is
furnished to do so, subject to the following conditions:

The  above  copyright  notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE  SOFTWARE  IS  PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED,  INCLUDING  BUT  NOT  LIMITED  TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS  FOR  A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR  ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

compilation: gcc -Wall -Werror root2jpg.c -o root2jpg -lX11 -ljpeg

*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <jpeglib.h>

// --------------------------------------------------------------------------

int exitmsg(int e) {

    char buf[256]; // buffer for error messages

    switch (e) {
        case 1:
            sprintf(buf, "value must be from 1 to 59");
            break;
        case 2:
            sprintf(buf, "error opening display");
            break;
        case 3:
            sprintf(buf, "error obtaining image");
            break;
        case 4:
            sprintf(buf, "error failed to open file");
            break;
    }

    fprintf(stderr, "roo2jpg: %s...\n", buf);

    return 1;

}

// --------------------------------------------------------------------------

int write_jpeg(XImage *img, const char* filename) {

    FILE* fp;
    unsigned long pixel;
    int x, y;
    char* tmp;
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;
    JSAMPROW row_ptr;

    fp = fopen(filename, "wb");
    if (!fp) return 1;

    // parse RGB values into tmp

    tmp = malloc(sizeof(char)*3*img->width*img->height);
    for (y = 0; y < img->height; y++) {
        for (x = 0; x < img->width; x++) {
            pixel = XGetPixel(img,x,y);
            tmp[y*img->width*3+x*3+0] = (pixel>>16);           // red
            tmp[y*img->width*3+x*3+1] = ((pixel&0x00ff00)>>8); // green
            tmp[y*img->width*3+x*3+2] = (pixel&0x0000ff);      // blue
        }
    }

    // fill in jpg structures

    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);
    jpeg_stdio_dest(&cinfo, fp);

    cinfo.image_width      = img->width;
    cinfo.image_height     = img->height;
    cinfo.input_components = 3;
    cinfo.in_color_space   = JCS_RGB;

    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, 85, TRUE);
    jpeg_start_compress(&cinfo, TRUE);

    // iterate through each scanline writing results to file

    while (cinfo.next_scanline < cinfo.image_height) {
        row_ptr = (JSAMPROW) &tmp[cinfo.next_scanline*\
            (img->depth>>3)*img->width];
        jpeg_write_scanlines(&cinfo, &row_ptr, 1);
    }

    // clean up

    free(tmp);
    jpeg_finish_compress(&cinfo);
    fclose(fp);

    return 0;

}

// --------------------------------------------------------------------------

int syntax(void) {

  system("clear");

  printf("%s","\n\n\
  roo2jpg screen-shot tool v0.98 [c]2012 Topcat Software LLC.\n\n\
  syntax: roo2jpg [-s seconds] [-f file.jpg]\n\n\
  where...\n\n\
  -s specifies sleep in secs. (1 to 59)\n\n\
  -f specifies filename\n\n");

  return 0;

}

// --------------------------------------------------------------------------

int main(int argc, char *argv[]) {

    if (argc < 5 || argc > 5) return syntax(); // bad syntax return
    int x = strcmp(argv[1], "-s");             // -s option
    int y = strcmp(argv[3], "-f");             // -f option
    if (x || y) return syntax();               // bad syntax return
    int n = atoi(argv[2]);                     // number of seconds to sleep
    if (n < 1 || n > 59) return exitmsg(1);    // out of range return error msg
    sleep(n);                                  // zzz... n seconds

    Display *dpy = XOpenDisplay(0);            // attempt to open display
    if (dpy == NULL) return exitmsg(2);        // else return error

    Window root = RootWindow(dpy,DefaultScreen(dpy)); // get root window
    XWindowAttributes rootAttributes;                 // and then...
    XGetWindowAttributes(dpy, root, &rootAttributes); // acquire attributes

    XImage *img = XGetImage(dpy,root,0,0,\
        rootAttributes.width,            \
        rootAttributes.height,           \
        XAllPlanes(),ZPixmap);          // nab XImage of root window

    if (img == NULL) {                  // if XGetImage() failed
        XCloseDisplay(dpy);             // close display and
        return exitmsg(3);              // return error
    } else {
        x = write_jpeg(img, argv[4]);   // write jpg
        XDestroyImage(img);             // release memory
        if (x != 0) {                   // if libjpg failed
            XCloseDisplay(dpy);         // close display and
            return exitmsg(4);          // return error
        }
    }

    XCloseDisplay(dpy);                 // close display and
    return 0;                           // bring it on home


}

// eof
/* 

root2xpm v0.99 [c]2012 Topcat Software LLC.

http://www.topcat.hypermart.net/index.html

Permission  is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in  the Software without restriction, including without limitation the rights
to  use,  copy,  modify,  merge, publish, distribute, sublicense, and/or sell
copies  of  the  Software,  and  to  permit  persons  to whom the Software is
furnished to do so, subject to the following conditions:

The  above  copyright  notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE  SOFTWARE  IS  PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED,  INCLUDING  BUT  NOT  LIMITED  TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS  FOR  A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR  ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

compilation: gcc -Wall -Werror root2xpm.c -o root2xpm -lX11 -lXpm

*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include </usr/include/X11/xpm.h>

// --------------------------------------------------------------------------

int exitmsg(int e) {

    char buf[256]; // buffer for error messages

    switch (e) {
        case 1:
            sprintf(buf, "value must be from 1 to 59");
            break;
        case 2:
            sprintf(buf, "error opening display");
            break;
        case 3:
            sprintf(buf, "error obtaining image");
            break;
        case 4:
            sprintf(buf, "libxpm error");
            break;
    }

    fprintf(stderr, "root2xpm: %s...\n", buf);

    return 1;

}

// --------------------------------------------------------------------------

int syntax(void) {

  system("clear");

  printf("%s","\n\n\
  root2xpm screen-shot tool v0.99 [c]2012 Topcat Software LLC.\n\n\
  syntax: root2xpm [-s seconds] [-f file.xpm]\n\n\
  where...\n\n\
  -s specifies sleep in secs. (1 to 59)\n\n\
  -f specifies filename\n\n");

  return 0;

}

// --------------------------------------------------------------------------

int main(int argc, char *argv[]) {

    if (argc < 5 || argc > 5) return syntax(); // bad syntax return
    int x = strcmp(argv[1], "-s");             // -s option
    int y = strcmp(argv[3], "-f");             // -f option
    if (x || y) return syntax();               // bad syntax return
    int n = atoi(argv[2]);                     // number of seconds to sleep
    if (n < 1 || n > 59) return exitmsg(1);    // out of range return error msg
    sleep(n);                                  // zzz... n seconds

    Display *dpy = XOpenDisplay(0);            // attempt to open display
    if (dpy == NULL) return exitmsg(2);        // else return error

    Window root = RootWindow(dpy,DefaultScreen(dpy)); // get root window
    XWindowAttributes rootAttributes;                 // and then...
    XGetWindowAttributes(dpy, root, &rootAttributes); // acquire attributes

    XImage *img = XGetImage(dpy,root,0,0,\
        rootAttributes.width,            \
        rootAttributes.height,           \
        XAllPlanes(),ZPixmap);          // nab XImage of root window

    if (img == NULL) {                  // if XGetImage() failed
        XCloseDisplay(dpy);             // close display and
        return exitmsg(3);              // return error
    } else {
        x = XpmWriteFileFromImage(dpy,argv[4],img,0, NULL); // write xpm
        XDestroyImage(img);                                 // release memory
        if (x == XpmOpenFailed) {       // if libxpm failed
            XCloseDisplay(dpy);         // close display and
            return exitmsg(4);          // return error
        }
    }

    XCloseDisplay(dpy);                 // close display and
    return 0;                           // bring it on home

}

// eof

Last edited by topcat-software (2011-12-24 17:20:24)

Offline

#2 2011-12-24 17:07:26

ewaller
Administrator
From: Pasadena, CA
Registered: 2009-07-13
Posts: 20,346

Re: screen-shot tools: root2jpg and root2xpm

topcat-software:
Welcome to Arch.  I hope you make the transition soon.  Your picture is a bit outside of our policy with regards to size.  I mostly concern myself with the byte count because many of our users are bandwidth limited.   As moderator, I would generally convert that to a link so that it is not displayed in-line.  But hey, it is the day before Christmas and I am in a good mood smile

The preferred method is to create a link to the full size picture, and inside that link, in-line a thumbnail so that readers can see the thumb, and click through it, if they wish.

Kind of like this : [ url=link to the big picture ][ img=link to the thumbnail [ /img ][ /url ]
Without the spaces to "break" the BBCode (of course).


Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
Sometimes it is the people no one can imagine anything of who do the things no one can imagine. -- Alan Turing
---
How to Ask Questions the Smart Way

Offline

#3 2011-12-24 17:21:49

topcat-software
Member
Registered: 2011-12-17
Posts: 20
Website

Re: screen-shot tools: root2jpg and root2xpm

Ahh... fixed now (inlined the link).

Offline

#4 2012-01-03 19:38:12

bocke
Member
Registered: 2011-07-15
Posts: 40

Re: screen-shot tools: root2jpg and root2xpm

I was looking for some simple examples how to do this (take a screenshot using xlib) a month or two ago. Thanx. smile

Offline

Board footer

Powered by FluxBB