5

I'm capturing an Android emulator screen using the command:

adb shell screencap -p /sdcard/screencap.png

But it is taking like 500ms to execute the command and save the png file, there is a faster way to capture the screen data? I don't really need the PNG file itself, just the 'image data', since I'm just creating the PNG and loading it into the .NET Bitmap class to read the pixels colors.

I need a faster way to capture the image, since I need like 10 images per second of the emulator screen to interact with it, so recording the screen to generate an video file is not a 'solution' for me.

Thanks

5
  • Where are you using the data? Are you pulling the PNG from the device, then processing it elsewhere? Commented May 10, 2017 at 18:53
  • I'm using MEmu emulator, so when I save it on /sdcard/ it saves in a shared folder on the computer
    – Imac
    Commented May 10, 2017 at 19:25
  • Did you contact the MEmu developers with your question? Commented May 10, 2017 at 19:35
  • Well, actually it's not really a MEmu problem, it's related to all emulators that I have to interact using ADB, like Nox, Memu, Droid4X, etc. Searching more about this, I saw someone saying that the main problem is to generate the .png file, not really to get the screen framebuffer (that generates the .png), but I'm not sure how to use the 'screencap' without generate a real .png or even if it's really possible
    – Imac
    Commented May 10, 2017 at 21:52
  • "but I'm not sure how to use the 'screencap' without generate a real .png" -- you can't. You can use the undocumented(?) tooling APIs that programs like Droid@Screen use. Or, as Ben suggests, have an Android app use the media projection APIs and send you the screenshots over the network. Commented May 10, 2017 at 21:57

7 Answers 7

3

Old question, but you could try adb shell screencap screen.dump. This will skip the step to convert the file to png and will generate a file which can be read in Hex.

There are 12 bytes of header and then the file starts with the pixel colors at position (0,0) (top left) as RGBA.

The final size of the file depends on the size of your display.

1
  • and how finally convert this to png/jpg or create Bitmap object?
    – user5636914
    Commented Jan 18, 2020 at 8:47
1

Generally speaking, adb exec-out screencap >screenshotName.raw for getting raw image data and adb exec-out screencap -p >screenshotName.png for png-file. Both are not the fastest though: raw file is large and the speed is limited to adb bandwidth; png is much better in terms of file size, but may take too long to compress.

Better way to transmit data is adb exec-out "screencap | gzip -1" >screenshotName.gz. '-1' is the lowest compression level. You may further experiment with compression levels (from -1 to -9). Gzip way faster compresses the image, though resulting size is a bit larger, but still is good enough to faster transmit resulting data. I've tried some sample images (interface screens as well as full-screen photos) and gzip-method is always two times or more faster.

0

AFAIK, no such way exists except you write and run an app on the target device. Then send it back through network. In emulator situation, use adb forward.

See createVirtualDisplay for more details.

2
  • Would 'adb forward' be faster taking the screenshot? Or it's just another way to communicate to the android device/emulator?
    – Imac
    Commented May 10, 2017 at 19:31
  • @IgorM Check the help of adb. It's just port forwarding with ideal maximum speed at less than 480Mbps (USB 2.0 typical). Most times it provides more than 20Mbps and I think it's enough for your need.
    – Ben
    Commented May 14, 2017 at 17:24
0

You can use adb shell screencap -j /sdcard/screencap.jpg

It will save image in the jpg format which for me was almost 3x faster than png.

1
  • adb does not have this option '-j'
    – Alex
    Commented Aug 2, 2022 at 19:51
0

I don't really need the PNG file itself, just the 'image data'

If you don't want the file to be saved, you don't need to specify image location:

adb shell screencap -p

Image data is PNG format printed out as a byte array. This is as fast as you can get with an adb command (typically 150ms on my PC with Bluestacks 4.2).

If you still want faster speed, this method using win32 api is perhaps the fastest. You need to make sure your emulator window is set to the correct size and visible on the screen.

0
image = check_output(["adb", "-s", emulator, "shell", "screencap -p"])
image = cv2.imdecode(np.fromstring(image, np.uint8), cv2.IMREAD_COLOR)

nearly 100 ms delay

-3

I am also working with Memu emulator for image recognition purposes. If you are on Windows you can use various tools to program a screenshot function of a specific handle of the Memu window.

I get around 24-36FPS of screenshots by calling native windows functions.

2
  • Welcome to Stack Overflow. Unfortunately, "you can use various tools" and "[call] native windows functions" doesn't provide any actual answer to the question. You would need to add much more detail into this answer to make it practically useful.
    – David Buck
    Commented Sep 24, 2020 at 7:18
  • What he is trying to say is on how to avoid the problem of slow USB connection by taking screenshots directly from your desktop while running a visual android emulator. instead of taking a screenshot on the device through adb. But this sadly was not the answer the OP was asking for
    – Alex
    Commented Aug 2, 2022 at 19:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.