The following procedure describes how to use Screen to capture a screenshot
of a single window. You can store the resulting screenshot in either a
pixmap or window buffer for further manipulation. This particular procedure describes
capturing the screenshot in a pixmap buffer and then writing the screenshot to a
bitmap.
Before you begin
Before proceeding, you are expected to have already created a Screen context and the
window that will be the target of your screenshot.
In the following procedure, the created context will be
referred to as screenshot_ctx.
The targeted window will be referred to as
screenshot_win.
-
Include the following files which are required to use some defined values:
#include <sys/stat.h>
#include <limits.h>
-
Define and implement the write_bitmap_header() function:
void write_bitmap_header(int nbytes, int fd, const int size[])
{
char header[54];
/* Set standard bitmap header */
header[0] = 'B';
header[1] = 'M';
header[2] = nbytes & 0xff;
header[3] = (nbytes >> 8) & 0xff;
header[4] = (nbytes >> 16) & 0xff;
header[5] = (nbytes >> 24) & 0xff;
header[6] = 0;
header[7] = 0;
header[8] = 0;
header[9] = 0;
header[10] = 54;
header[11] = 0;
header[12] = 0;
header[13] = 0;
header[14] = 40;
header[15] = 0;
header[16] = 0;
header[17] = 0;
header[18] = size[0] & 0xff;
header[19] = (size[0] >> 8) & 0xff;
header[20] = (size[0] >> 16) & 0xff;
header[21] = (size[0] >> 24) & 0xff;
header[22] = -size[1] & 0xff;
header[23] = (-size[1] >> 8) & 0xff;
header[24] = (-size[1] >> 16) & 0xff;
header[25] = (-size[1] >> 24) & 0xff;
header[26] = 1;
header[27] = 0;
header[28] = 32;
header[29] = 0;
header[30] = 0;
header[31] = 0;
header[32] = 0;
header[33] = 0;
header[34] = 0; /* image size*/
header[35] = 0;
header[36] = 0;
header[37] = 0;
header[38] = 0x9;
header[39] = 0x88;
header[40] = 0;
header[41] = 0;
header[42] = 0x9l;
header[43] = 0x88;
header[44] = 0;
header[45] = 0;
header[46] = 0;
header[47] = 0;
header[48] = 0;
header[49] = 0;
header[50] = 0;
header[51] = 0;
header[52] = 0;
header[53] = 0;
/* Write bitmap header to file */
write(fd, header, sizeof(header));
}
-
Create variables for the pixmap, the pixmap buffer, the pixmap buffer pointer, and the stride:
screen_pixmap_t screen_pix;
screen_buffer_t screenshot_buf;
char *screenshot_ptr = NULL;
int screenshot_stride = 0;
-
Create other variables necessary to support the
Screen API calls and the writing
of our screenshot to a bitmap.
In this procedure, you will declare several integer variables to help in setting the
pixmap and its properties. You will also need variables associated with the writing
of the screenshot to bitmap, for example, fname stores the path and filename
to which to write the screenshot. Ensure
that you have appropriate permissions to access the directory path of the file.
char header[54];
char app_directory[PATH_MAX];
getcwd(app_directory[PATH_MAX]; /* Get the application directory on the device. */
char fname[PATH_MAX];
snprintf(fname, PATH_MAX, "%s/data/window_screenshot.bmp", app_directory);
int nbytes;
int fd;
int i;
int usage, format;
int size[2];
-
Create the pixmap for the screenshot and set the usage flag and format properties:
screen_create_pixmap(&screen_pix, screenshot_ctx);
usage = SCREEN_USAGE_READ | SCREEN_USAGE_NATIVE;
screen_set_pixmap_property_iv(screen_pix, SCREEN_PROPERTY_USAGE, &usage);
format = SCREEN_FORMAT_RGBA8888;
screen_set_pixmap_property_iv(screen_pix, SCREEN_PROPERTY_FORMAT, &format);
-
Set the buffer size of the pixmap for the screenshot:
Set an appropriate buffer size for the pixmap. The pixmap buffer size doesn't
have to necessarily match the size of the source. Scaling will be applied to make the
screenshot fit into the buffer provided.
size[0] = 200;
size[1] = 200;
screen_set_pixmap_property_iv(screen_pix, SCREEN_PROPERTY_BUFFER_SIZE, size);
-
Create the pixmap buffer for the screenshot and get the buffer handle, the pointer, and the stride.
Memory is allocated for your pixmap buffer; this is the buffer where the pixels
from the source window will be copied to:
screen_create_pixmap_buffer(screen_pix);
screen_get_pixmap_property_pv(screen_pix, SCREEN_PROPERTY_RENDER_BUFFERS,
(void**)&screenshot_buf);
screen_get_buffer_property_pv(screenshot_buf, SCREEN_PROPERTY_POINTER,
(void**)&screenshot_ptr);
screen_get_buffer_property_iv(screenshot_buf, SCREEN_PROPERTY_STRIDE,
&screenshot_stride);
-
Take the window screenshot:
screen_read_window(screenshot_win, screenshot_buf, 0, NULL, 0);
This function takes five arguments: the target
of the screenshot, the pixmap buffer, the number of rectangles defining the
area of capture, the array of integers representing rectangles of the area
of capture, and the mutex flag. The arguments related to the area of capture
are 0 and NULL because in this example you are capturing the target area in
its entirety rather than a specific rectangular area. The last argument
(which represents the mutex flag) should always be 0.
-
Create the bitmap file with appropriate permissions; prepare the header and write the buffer contents to
the file. Afterwards, close the file:
fd = creat(fname, S_IRUSR | S_IWUSR);
nbytes = size[0] * size[1] * 4;
write_bitmap_header(nbytes, fd, size);
for (i = 0; i < size[1]; i++) {
write(fd, screenshot_ptr + i * screenshot_stride, size[0] * 4);
}
close(fd);
The value of nbytes represents the
calculated size of the bitmap and is used in the header
of the bitmap itself.
Although any instances created are destroyed when the application exits, it is best
practice to destroy any window, pixmap, and context instances that you created but
no longer require.
In this example, you should destroy the pixmap that you created
to perform the screenshot. After the pixmap buffer has been
used to create the bitmap, the pixmap, and its buffer are no
longer required. Therefore you should perform the appropriate
cleanup.
screen_destroy_pixmap(screen_pix);