我需要获取安卓手机屏幕上特定点的颜色信息。
是否可以通过ADB实现?
目前,我正在使用内置命令screencap来捕获整个屏幕,然后读取特定点的颜色。 但是,这样做速度太慢了。
我会回答自己的问题。答案可能与设备相关(nexus7 2013),您可以根据自己的设备进行调整。
1.首先,我发现命令 screencap screen.png
非常慢,因为它花费大部分时间将图像转换为png文件类型。因此,为了节省时间,第一步是将屏幕转储到原始数据文件中。
adb shell
screencap screen.dump
2.检查文件大小。我的屏幕分辨率为1920*1200,文件大小为9216012字节。注意到 9216012 = 1920 * 1200 * 4 +12,我猜测数据文件使用4字节来存储每个像素的信息,并使用另外12字节进行某些神秘的操作。再截取几个屏幕,我发现每个文件的头12个字节都相同。因此,额外的12个字节在数据文件的开头。
3.现在,使用dd
和hd
就很简单了。假设我想获取(x,y)处的颜色:
let offset=1200*$y+$x+3
dd if='screen.dump' bs=4 count=1 skip=$offset 2>/dev/null | hd
我得到的输出如下:
00000000: 4b 73 61 ff s 21e
sum 21e
其中的4b 73 61 ff
就是我的答案。
如果您的手机已经获取了root权限,并且您知道它的framebuffer
格式,那么您可以使用dd
和hd
(十六进制转储)直接从framebuffer
文件中获取像素表示:
adb shell "dd if=/dev/graphics/fb0 bs=<bytes per pixel> count=1 skip=<pixel offset> 2>/dev/null | hd"
<每像素字节数>= 4
,<像素偏移量> = Y *宽度+ X
,但在您的手机上可能会有所不同。adb shell "dd if=/dev/graphics/fb0 bs=4 count=1 skip=1000 2>/dev/null | hd"
,它返回了 Usage: hd [-b base] [-c count] [-r delay] file
。看起来 'hd' 是在我的 bash shell 中执行而不是 adb shell。我尝试了以下操作:I - superweijiafengroot
权限,所以dd
没有产生任何输出供hd
处理。 - Alex P.adb shell
su
dd if=/dev/graphics/fb0 bs=4 count=1 skip=1000 2>/dev/null | hd
它返回类似于
00000000: 00 00 00 00 s 0
sum 0
的内容。 - superweijiafeng00 00 00 00
。 - Alex P.C6 7A 25 62
,如何将其转换为RGB值? - CSJ基于之前被接受的答案,我编写了一个 SH 函数,能够计算缓冲区等内容,以便在我的手机上即开即用。
用法:
GetColorAtPixel X Y
GIST:https://gist.github.com/ThomazPom/d5a6d74acdec5889fabcb0effe67a160
widthheight=$(wm size | sed "s/.* //")
width=$(($(echo $widthheight | sed "s/x.*//g" )+0))
height=$(($(echo $widthheight | sed "s/.*x//g" )+0))
GetColorAtPixel () {
x=$1;y=$2;
rm ./screen.dump 2> /dev/null
screencap screen.dump
screenshot_size=$(($(wc -c < ./screen.dump)+0));
buffer_size=$(($screenshot_size/($width*height)))
let offset=$width*$y+$x+3
color=$(dd if="screen.dump" bs=$buffer_size count=1 skip=$offset 2>/dev/null | hd | grep -Eo "([0-9A-F]{2} )" |sed "s/[^0-9A-F]*\$//g" | sed ':a;N;$!ba;s/\n//g' |cut -c3-8)
echo $color;
}
还有一种替代版本(当我将其嵌入sh文件中时,第一个版本对我来说无法正常工作,原因是某些未知的默认hexdump行为问题)
widthheight=$(wm size | sed "s/.* //")
width=$(($(echo $widthheight | sed "s/x.*//g" )+0))
height=$(($(echo $widthheight | sed "s/.*x//g" )+0))
GetColorAtPixel () {
x=$1;y=$2;
rm ./screen.dump 2> /dev/null
screencap screen.dump
screenshot_size=$(($(wc -c < ./screen.dump)+0));
buffer_size=$(($screenshot_size/($width*height)))
let offset=$width*$y+$x+3
color=$(dd if="screen.dump" bs=$buffer_size count=1 skip=$offset 2>/dev/null | /system/xbin/hd | awk '{ print toupper($0) }' | grep -Eo "([0-9A-F]{2})+" | sed ':a;N;$!ba;s/\n//g' | cut -c9-14 )
echo $color;
}
hexdump -C
而不是 hd
吗?也许这可以解决嵌入问题。 - Zebiano
hd
或hexdump
用于显示二进制数据。例如,如果您在文本文件中有 "123",则hd THE-FILE
将得到31 32 33
。请问您的命令是什么? - superweijiafeng