Screenshot of the Nexus One from adb?

2019-01-20 23:05发布

My goal is to be able to type a one word command and get a screenshot from a rooted Nexus One attached by USB.

So far, I can get the framebuffer which I believe is a 32bit xRGB888 raw image by pulling it like this:

adb pull /dev/graphics/fb0 fb0

From there though, I'm having a hard time getting it converted to a png. I'm trying with ffmpeg like this:

ffmpeg -vframes 1 -vcodec rawvideo -f rawvideo -pix_fmt rgb8888 -s 480x800 -i fb0 -f image2 -vcodec png image.png

That creates a lovely purple image that has parts that vaguely resemble the screen, but it's by no means a clean screenshot.

14条回答
叼着烟拽天下
2楼-- · 2019-01-20 23:45

A vastly easier solution for ICS is to use the following from the command line

adb shell /system/bin/screencap -p /sdcard/screenshot.png
adb pull /sdcard/screenshot.png screenshot.png

This'll save the screenshot.png file in the current directory.

Tested on a Samsung Galaxy SII & SII running 4.0.3.

查看更多
可以哭但决不认输i
3楼-- · 2019-01-20 23:48

Using my HTC Hero (and hence adjusting from 480x800 to 320x480), this works if I use rgb565 instead of 8888:

ffmpeg -vframes 1 -vcodec rawvideo -f rawvideo -pix_fmt rgb565 -s 320x480 -i fb0 -f image2 -vcodec png image.png
查看更多
甜甜的少女心
4楼-- · 2019-01-20 23:49

Now we have got a single line command to take a screenshot. The command as follows:

adb shell screencap -p | perl -pe 's/\x0D\x0A/\x0A/g' > screen.png

Type the above command in your terminal and press enter. If you want the screenshot to be stored in any specific location, then give the path (or) directory before screen.png.

Source.

查看更多
做自己的国王
5楼-- · 2019-01-20 23:56

On the MyTouch Slide 3G, I ended up with the red and blue channels swapped in my screenshots. Here's the correct ffmpeg incantation for anyone else in that situation: (the notable part: -pix_fmt bgr32)

ffmpeg -vframes 1 -vcodec rawvideo -f rawvideo -pix_fmt bgr32 -s 320x480 -i fb0 -f image2 -vcodec png image.png

Thanks to Patola for the handy shell script! At least for my phone, no mogrification is necessary to correctly orient for portrait mode (320x480), and so the end of his script becomes:

# assuming 'down' is towards the keyboard or usb jack 
# in landscape and protrait modes respectively
(( ${PORTRAIT} )) || mogrify -rotate 270 "${outputfile}"

/bin/rm -f fb0.$$ fb0b.$$
查看更多
倾城 Initia
6楼-- · 2019-01-20 23:58

I think rgb32torgb888.py should be

 sys.stdout.write(colour[0])
 sys.stdout.write(colour[1])
 sys.stdout.write(colour[2])
查看更多
仙女界的扛把子
7楼-- · 2019-01-21 00:01

A little elaborate/excessive but it handles both screencap and framebuffer scenarios (as well as figuring out the resolution too).

#!/bin/bash
#
# adb-screenshot - simple script to take screenshots of android devices
#
# Requires: 'ffmpeg' and 'adb' to be somewhere in the PATH
#
# Author: Kevin C. Krinke <kevin@krinke.ca>
# License: Public Domain

# globals / constants
NAME=$(basename $0)
TGT=~/Desktop/${NAME}.png
SRC=/sdcard/${NAME}.png
TMP=/tmp/${NAME}.$$
RAW=/tmp/${NAME}.raw
FFMPEG=$(which ffmpeg)
ADB=$(which adb)
DD=$(which dd)
USB_DEVICE=""

# remove transitory files if exist
function cleanup () {
    [ -f "${RAW}" ] && rm -f "${RAW}"
    [ -f "${TMP}" ] && rm -f "${TMP}"
    [ -z "$1" ] && die "aborting process now."
    exit 0
}

# exit with an error
function die () {
    echo "Critical Error: $@"
    exit 1
}

# catch all signals and cleanup / dump
trap cleanup \
    SIGHUP SIGINT SIGQUIT SIGILL SIGTRAP SIGABRT SIGEMT SIGFPE \
    SIGKILL SIGBUS SIGSEGV SIGSYS SIGPIPE SIGALRM SIGTERM SIGURG \
    SIGSTOP SIGTSTP SIGCONT SIGCHLD SIGTTIN SIGTTOU SIGIO SIGXCPU \
    SIGXFSZ SIGVTALRM SIGPROF SIGWINCH SIGINFO SIGUSR1 SIGUSR2

# adb is absolutely required
[ -x "${ADB}" ] || die "ADB is missing!"

# cheap getopt
while [ $# -gt 0 ]
do
    case "$1" in
        "-h"|"--help")
            echo "usage: $(basename $0) [-h|--help] [-s SERIAL] [/path/to/output.png]"
            exit 1
            ;;
        "-s")
            [ -z "$2" ] && die "Missing argument for option \"-s\", try \"${NAME} --help\""
            HAS_DEVICE=$(${ADB} devices | grep "$2" )
            [ -z "${HAS_DEVICE}" ] && die "No device found with serial $2"
            USB_DEVICE="$2"
            ;;
        *)
            [ -n "$1" -a -d "$(dirname $1)" ] && TGT="$1"
            ;;
    esac
    shift
done

# prep target with fire
[ -f "${TGT}" ] && rm -f "${TGT}"

# tweak ADB command line
if [ -n "${USB_DEVICE}" ]
then
    ADB="$(which adb) -s ${USB_DEVICE}"
fi

# calculate resolution
DISPLAY_RAW=$(${ADB} shell dumpsys window)
HRES=$(echo "${DISPLAY_RAW}" | grep SurfaceWidth  | head -1 | perl -pe 's/^.*\bSurfaceWidth\:\s*(\d+)px\b.*$/$1/')
VRES=$(echo "${DISPLAY_RAW}" | grep SurfaceHeight | head -1 | perl -pe 's/^.*\bSurfaceHeight\:\s*(\d+)px\b.*$/$1/')
RES=${HRES}x${VRES}

# check for screencap binary
HAS_SCREENCAP=$(${ADB} shell "[ -x /system/bin/screencap ] && echo 1 || echo 0" | perl -pe 's/\D+//g')
if [ "$HAS_SCREENCAP" == "1" ]
then # use screencap to get the image easy-peasy
    echo -n "Getting ${RES} screencap... "
    ( ${ADB} shell /system/bin/screencap ${SRC} 2>&1 ) > /dev/null
    [ "$?" != "0" ] && die "Failed to execute screencap"
    ( ${ADB} pull ${SRC} ${TMP} 2>&1 ) > /dev/null
    [ "$?" != "0" ] && die "Failed to pull png image"
    ( ${ADB} shell rm ${SRC} 2>&1 ) > /dev/null
    [ "$?" != "0" ] && die "Failed to remove png image"
    mv ${TMP} ${TGT}
    echo "wrote: ${TGT}"
else # fetch a framebuffer snapshot
    # ffmpeg is only needed if device is pre-ICS
    [ -x "${FFMPEG}" ] || die "FFMPEG is missing!"
    [ -x "${DD}" ] || die "DD is missing!"
    echo -n "Getting ${RES} framebuffer... "
    ( ${ADB} pull /dev/graphics/fb0 ${RAW} 2>&1 ) > /dev/null
    [ "$?" != "0" ] && die "Failed to pull raw image data"
    # calculate dd parameters
    COUNT=$((HRES*4))
    BLOCKSIZE=$((VRES))
    ( ${DD} bs=${BLOCKSIZE} count=${COUNT} if=${RAW} of=${TMP} 2>&1 ) > /dev/null
    [ "$?" != "0" ] && die "Failed to realign raw image data"
    ( ${FFMPEG} -vframes 1 -vcodec rawvideo -f rawvideo -pix_fmt rgb32 -s ${RES} -i ${TMP} -f image2 -vcodec png ${TGT} 2>&1 ) > /dev/null
    [ "$?" != "0" ] && die "Failed to encode PNG image"
    echo "wrote: ${TGT}"
fi

# exit app normal
cleanup 1
查看更多
登录 后发表回答