Reputation: 2651
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.
Upvotes: 10
Views: 8830
Reputation: 93
To read adb screencap raw format in python:
from PIL import Image
Image.frombuffer('RGBA', (1920, 1080), raw[12:], 'raw', 'RGBX', 0, 1)
The most important part is skipping the header, as mentioned in @Emmanuel's answer
Note that (1920, 1080) are your device resolution which can be obtained with
adb shell wm size
Hopefully this will save someone 12 hours investigating why cv2.matchTemplate has different match on almost identical images.
Upvotes: 5
Reputation: 4420
Format:
width
height
pixel format
width
* heigth
* bytespp
) bytes as byte array - image data
, where bytespp
is bytes per pixels and depend on pixel format
. Usually bytespp
is 4.Info from source code of screencap.
For your example:
00000000 d0 02 00 00 00 05 00 00 01 00 00 00 1e 1e 1e ff
d0 02 00 00
- width - uint32 0x000002d0 = 72000 05 00 00
- height - uint32 0x00000500 = 128001 00 00 00
- pixel format - uint32 0x00000001 = 1 = PixelFormat.RGBA_8888
=> bytespp = 4
=> RGBA1e 1e 1e ff
- first pixel data - R = 0x1e; G = 0x1e; B = 0x1e; A = 0xff;
Pixels with data stored in array of bytes with size 720*1280*4.
Upvotes: 19
Reputation: 3407
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
Upvotes: 7