una samsung pantalla hacer fisicos como celular capturar captura botones android graphics ffmpeg screenshot

samsung - como capturar pantalla en android



¿Captura de pantalla del Nexus One de adb? (14)

Mi objetivo es poder escribir un comando de una palabra y obtener una captura de pantalla de un Nexus One conectado por USB.

Hasta ahora, puedo obtener el framebuffer que creo que es una imagen en bruto de 32bit xRGB888 tirando de él de esta manera:

adb pull /dev/graphics/fb0 fb0

A partir de ahí, estoy teniendo dificultades para convertirlo a png. Estoy intentando con ffmpeg así:

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

Eso crea una imagen púrpura hermosa que tiene partes que se asemejan vagamente a la pantalla, pero de ninguna manera es una captura de pantalla limpia.


Ahora tenemos un comando de una sola línea para tomar una captura de pantalla. El comando de la siguiente manera:

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

Escriba el comando de arriba en su terminal y presione enter. Si desea que la captura de pantalla se almacene en cualquier ubicación específica, proporcione el directorio de ruta (o) antes de screen.png .

Source


Creo que rgb32torgb888.py debería ser

sys.stdout.write(colour[0]) sys.stdout.write(colour[1]) sys.stdout.write(colour[2])


Creo que todos los framebuffers hasta la fecha son RGB 565, no 888.


En el MyTouch Slide 3G, terminé con los canales rojo y azul intercambiados en mis capturas de pantalla. Aquí está el encantamiento ffmpeg correcto para cualquier otra persona en esa situación: (la parte notable: -pix_fmt bgr32 )

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

¡Gracias a Patola por el útil script de shell! Al menos para mi teléfono, no es necesaria ninguna mogrificación para orientarme correctamente para el modo vertical (320x480), por lo que el final de su secuencia de comandos se convierte en:

# 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.$$


En realidad, hay otra habilidad muy simple para capturar capturas de pantalla de su dispositivo Android: escriba un guion simple 1.script como este:

# Imports the monkeyrunner modules used by this program from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice # Connects to the current device, returning a MonkeyDevice object device = MonkeyRunner.waitForConnection() # Takes a screenshot result = device.takeSnapshot() # Writes the screenshot to a file result.writeToFile(''1.png'',''png'')

y llame a monkeyrunner 1.script .


Espero que mi script pueda ser de alguna utilidad. Lo uso en mi pestaña galaxy y funciona perfectamente, pero es posible cambiar la resolución predeterminada. Sin embargo, requiere el shell "zsh":

#!/bin/zsh # These settings are for the galaxy tab. HRES=600 VRES=1024 usage() { echo "Usage: $0 [ -p ] outputfile.png" echo "-- takes screenshot off your Galaxy Tab Android phone." echo " -p: portrait mode" echo " -r X:Y: specify resolution, e.g. -r 480:640 specifies that your cellphone has 480x640 resolution." exit 1 } PORTRAIT=0 # false by default umask 022 [[ ! -w . ]] && { echo "*** Error: current directory not writeable." usage } [[ ! -x $(which mogrify) ]] && { echo "*** Error: ImageMagick (mogrify) is not in the PATH!" usage } while getopts "pr:" myvar do [[ "$myvar" == "p" ]] && PORTRAIT=1 [[ "$myvar" == "r" ]] && { testhres="${OPTARG%%:*}" # remove longest-matching :* from end testvres="${OPTARG##*:}" # remove longest-matchung *: from beginning if [[ $testhres == <0-> && $testvres == <0-> ]] # Interval: from 0 to infinite. Any value would be: <-> then HRES=$testhres VRES=$testvres else echo "Error! One of these values - ''${testhres}'' or ''${testvres}'' - is not numeric!" usage fi } done shift $((OPTIND-1)) [[ $# < 1 ]] && usage outputfile="${1}" blocksize=$((HRES*4)) count=$((VRES)) adb pull /dev/graphics/fb0 fb0.$$ /bin/dd bs=$blocksize count=$count if=fb0.$$ of=fb0b.$$ /usr/bin/ffmpeg -vframes 1 -vcodec rawvideo -f rawvideo -pix_fmt rgb32 -s ${VRES}x${HRES} -i fb0b.$$ -f image2 -vcodec png "${outputfile}" if (( ${PORTRAIT} )) then mogrify -rotate 270 "${outputfile}" else mogrify -flip -flop "${outputfile}" fi /bin/rm -f fb0.$$ fb0b.$$


Esto podría estar relacionado con el problema de la lectura de datos binarios de stdout del shell de adb, donde adb intenta realizar la conversión de LF a CRLF (probablemente sea solo la versión de Windows de adb). Personalmente tuve problemas con la conversión / n a / r / r / n así que, como una forma de convertir esto, es bueno usar el código en [ 1 ] o usarlo.

para mí correrlo con (en cygwin): adb shell ''cat /dev/graphics/fb0'' | perl -pi -e ''s//r/r/n//n/g'' adb shell ''cat /dev/graphics/fb0'' | perl -pi -e ''s//r/r/n//n/g'' parecía ayudar

aparte de eso, intenta comparar el Ancho y la altura con el tamaño del archivo. El tamaño del archivo debe ser uniformemente divisible por Width * height si ese no es el caso, entonces la herramienta adb está haciendo automáticamente las cosas por usted o es un formato más exótico que rgb545 o rgb8888.

si solo se trata de un problema de color (es decir, todo en la imagen resultante está en el lugar correcto), puede considerar intercambiar los canales Rojo y Azul, ya que algunos sistemas (en general) usan orden de bytes BGRA en lugar de RGBA.


Parece que el buffer de cuadro de N1 usa codificación RGB32 (32 bits por píxel).

Aquí está mi script usando ffmpeg:

adb pull /dev/graphics/fb0 fb0 dd bs=1920 count=800 if=fb0 of=fb0b ffmpeg -vframes 1 -vcodec rawvideo -f rawvideo -pix_fmt rgb32 -s 480x800 -i fb0b -f image2 -vcodec png fb0.png

Otra forma derivada del método ADP1 descrito aquí http://code.lardcave.net/entries/2009/07/27/132648/

adb pull /dev/graphics/fb0 fb0 dd bs=1920 count=800 if=fb0 of=fb0b python rgb32torgb888.py <fb0b >fb0b.888 convert -depth 8 -size 480x800 RGB:fb0b.888 fb0.png

Script de Python ''rgb32torgb888.py'':

import sys while 1: colour = sys.stdin.read(4) if not colour: break sys.stdout.write(colour[2]) sys.stdout.write(colour[1]) sys.stdout.write(colour[0])


Si tiene dos2unix instalado, entonces el siguiente

adb shell screencap -p | dos2unix > screen.png


Un poco complicado / excesivo, pero maneja tanto el escenario screencap como el framebuffer (así como también descifrar la resolución).

#!/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 <[email protected]> # 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


Una forma de automatizar por completo este proceso es crear una secuencia de comandos que agregue la marca de tiempo curada al nombre del archivo. De esta manera, no tiene que escribir el nombre del archivo usted mismo, todas las capturas de pantalla tienen un nombre diferente, y las capturas de pantalla están ordenadas por tiempo.

Ejemplo de script bash:

#! /bin/bash filename=$(date +"_%Y-%m-%d-%H:%M") /PATH_TO_ANDROID_SDK/platform-tools/adb -d shell screencap -p | perl -pe ''s//x0D/x0A//x0A/g'' > screenshot$filename.png

Esto creará un archivo llamado como screenshot_2014-01-07-10: 31.png


Una solución mucho más fácil para ICS es usar lo siguiente desde la línea de comando

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

Esto guardará el archivo screenshot.png en el directorio actual.

Probado en un Samsung Galaxy SII y SII con la versión 4.0.3.


Usar mi HTC Hero (y por lo tanto ajustar desde 480x800 a 320x480), esto funciona si uso rgb565 en lugar de 8888:

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


rgb565 lugar de 8888 también funciona en emulador