Search code examples
androidpythonadbpython-imaging-library

What format does "adb screencap /sdcard/screenshot.raw" produce? (without "-p" flag)


I am looking to use adb screencap utility without the -p flag. I imagined output will be dumped in raw format, but doesn't look like it. My attempts of opening the raw image file with Pillow (python) library resulted in:

$ adb pull /sdcard/screenshot.raw screenshot.raw
$ python
>>> from PIL import Image
>>> Image.open('screenshot.raw')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/....../lib/python2.7/site-packages/PIL/Image.py", line 2025, in open
    raise IOError("cannot identify image file")
IOError: cannot identify image file

Found out not the right way to read raw images like this, I even gave the following a shot: How to read a raw image using PIL?

>>> with open('screenshot.raw', 'rb') as f:
...     d = f.read()
... 
>>> from PIL import Image
>>> Image.frombuffer('RGB', len(d), d)
__main__:1: RuntimeWarning: the frombuffer defaults may change in a future release; for portability, change the call to read:
  frombuffer(mode, size, data, 'raw', mode, 0, 1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/..../lib/python2.7/site-packages/PIL/Image.py", line 1896, in frombuffer
    return frombytes(mode, size, data, decoder_name, args)
  File "/Users/..../lib/python2.7/site-packages/PIL/Image.py", line 1821, in frombytes
    im = new(mode, size)
  File "/Users/..../lib/python2.7/site-packages/PIL/Image.py", line 1787, in new
    return Image()._new(core.fill(mode, size, color))
TypeError: must be 2-item sequence, not int

All possible mode option lead to same TypeError exception.

Here is what hexdump utility reveals:

$ hexdump -C img.raw | head
00000000  d0 02 00 00 00 05 00 00  01 00 00 00 1e 1e 1e ff  |................|
00000010  1e 1e 1e ff 1e 1e 1e ff  1e 1e 1e ff 1e 1e 1e ff  |................|
*
000038c0  1e 1e 1e ff 1e 1e 1e ff  21 21 21 ff 2b 2b 2b ff  |........!!!.+++.|
000038d0  1e 1e 1e ff 1e 1e 1e ff  1e 1e 1e ff 1e 1e 1e ff  |................|
*
00004400  1e 1e 1e ff 1e 1e 1e ff  47 47 47 ff 65 65 65 ff  |........GGG.eee.|
00004410  20 20 20 ff 1e 1e 1e ff  1e 1e 1e ff 1e 1e 1e ff  |   .............|
00004420  1e 1e 1e ff 1e 1e 1e ff  1e 1e 1e ff 1e 1e 1e ff  |................|
*

On osx:

$ file screenshot.raw 
screenshot.raw: data

screencap help page doesn't reveal much either about format of output data without -p flag:

$ adb shell screencap -h
usage: screencap [-hp] [FILENAME]
   -h: this message
   -p: save the file as a png.
If FILENAME ends with .png it will be saved as a png.
If FILENAME is not given, the results will be printed to stdout.

Solution

  • Thanks to the extract of your file , I guess your raw file is formated as width x height then the whole set of RGBA pixels (32 bits) (width x height times) Here I see you get a 720x1280 image captured..

    May the ImageMagick toolset help you to view/convert it in a more appropriate file format. Here below a sample that may help you (ImageMagick convert command, for osx see http://cactuslab.com/imagemagick/ )

    # skip header info  
    dd if=screenshot.raw of=screenshot.rgba skip=12 bs=1
    # convert rgba to png
    convert -size 720x1280 -depth 8 screenshot.rgba screenshot.png
    

    If it doesn't work you may try changing skip=12 by skip=8 and/or 720x1280 by 1280x720 ..

    Hope that help