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