How to do a framebuffer screenshot

I’ll explain how to do framebuffer screenshots on 16-bit and 32-bit framebuffer. For 16-bit this is fully based on http://docs.blackfin.uclinux.org/doku.php?id=framebuffer

Capturing screenshots

Whatever the bit-depth of your framebuffer, the first step is to capture the frambuffer raw data on the board:

cat /dev/fb0 > screen.raw

Now the you need to take the raw image, and convert it to a standard image format. This step depends on what type of display is there

Converting 16-bit Framebuffer screenshot (RGB565) into png

To convert the raw rgb data extracted from /dev/fb0, use iraw2png perl script

#!/usr/bin/perl -w

$w = shift || 240;
$h = shift || 320;
$pixels = $w * $h;

open OUT, "|pnmtopng" or die "Can't pipe pnmtopng: $!\n";

printf OUT "P6%d %d\n255\n", $w, $h;

while ((read STDIN, $raw, 2) and $pixels--) {
   $short = unpack('S', $raw);
   print OUT pack("C3",
      ($short & 0xf800) >> 8,
      ($short & 0x7e0) >> 3,
      ($short & 0x1f) << 3);
}

close OUT;

To do the conversion, type the following command in the host:

./iraw2png 640 480 < screen.raw > screen.png

where 640 and 480 are respectively the width and height of your framebuffer.

This has been tried on a 16-bit framebuffer on EM8620 series.

Converting 32-bit Framebuffer screenshot (ARGB, RGBA, BGRA…) into png

The solution proposed here is not as neat as the blackfin’s solution for 16-bit framebuffer, however this still works.

First you’ll need to install Gimp 2 in your computer (Linux or Windows).

Then open the screenshot as a raw file (Select File Type: Raw Image Data) in Gimp2, enter the width and height as well of the color arrangement, RGB, RGBA etc…

If the image looks OK, but the colors do not match, then that probably because the R (red), G (Green), B(Blue) and A (Alpha) fields are mixed up. You’ll just need to use the Channel Mixer to re-arrange or permute the colors. (e.g. RGBA -> BGRA). To get to that menu click on Colours->Components->Channel Mixer and there you’ll be able to set the Red channel to Blue and the Blue Channel to Red or whatever settings required to get the right colors.

Finally simply save this file as PNG or any format you like.

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter

Categories: Graphics, Linux, Linux 2.4, Linux 2.6, Processors, Sigma Designs EM862X, Sigma Designs SMP863X Tags: Linux, capture, framebuffer, screenshot
  1. xuan
    October 19th, 2012 at 16:27 | #1

    Hi, I try to change ./iraw2png to “Converting 32-bit Framebuffer screenshot” like this:
    1 #!/usr/bin/perl -w
    2
    3 $w = shift || 240;
    4 $h = shift || 320;
    5 $pixels = $w * $h;
    6
    7 open OUT, “|pnmtopng” or die “Can’t pipe pnmtopng: $!\n”;
    8
    9 printf OUT “P6%d %d\n255\n”, $w, $h;
    10
    11 while ((read STDIN, $raw, 4) and $pixels–) {
    12 $short = unpack(‘L’, $raw);
    13 print OUT pack(“C4″,
    14 ($short & 0xff000000) >> 24,
    15 ($short & 0xff0000) >> 16,
    16 ($short & 0xff00) >> 8,
    17 ($short & 0xff) );
    18 }
    19
    20 close OUT;
    but it doesn’t work. did you tried it?

  2. October 19th, 2012 at 20:37 | #2

    @xuan
    No, I had never try to run a script to convert 32-bit raw data into PNG.
    It should be feasible. If it does not work, it could be because of the R,G,B,A order or the format of your PNG file.
    The easiest to debug would be to go with a easy 32-bit raw file (e.g. 1 color).

  3. nniico
    January 3rd, 2013 at 19:13 | #3

    @xuan
    For 32-bit pictures, you can use imagemagick directly. On my desktop computer, I had to remove the alpha channel and swap the channels : RGBA -> BGR

    $ convert -depth 8 -size 1920×1080 rgba:screen.raw[0] -alpha off -separate -swap 0,2 -combine screen.png

    For 24-bit images, it’s the same without the alpha channel.

  4. nniico
    January 3rd, 2013 at 23:12 | #4

    This modified version of “Converting 32-bit Framebuffer screenshot” is working for me :

    #!/usr/bin/perl -w
    $w = shift || 240;
    $h = shift || 320;
    $pixels = $w * $h;

    open OUT, “|pnmtopng” or die “Can’t pipe pnmtopng: $!\n”;
    printf OUT “P6\n%d %d\n255\n”, $w, $h;

    while ((read STDIN, $raw, 4) and $pixels–) {
    $short = unpack(‘N’, $raw);
    print OUT pack(‘C3′,
    ($short >> 8) & 0xff,
    ($short >> 16) & 0xff,
    ($short >> 24) & 0xff
    );
    }

    close OUT;

  5. September 25th, 2013 at 17:04 | #5

    @nniico
    I’m using imagemagick too. I issue this command on the desktop:

    ssh [email protected] “cat /dev/fb0 | gzip” | zcat | convert -depth 8 -size 480×272 rgba:-[0] -alpha off -separate -swap 0,2 -combine $(date +’%Y-%m-%d-%H-%M-%S-%N’).png

    where 10.10.1.23 is the IP address of the board.
    gzip and zcat can be left out, it’s just a habit of mine to always compress when I pipe something over ssh.

  1. No trackbacks yet.