【问题标题】:How can I get the color of a screen pixel THROUGH ADB如何通过 ADB 获取屏幕像素的颜色
【发布时间】:2020-05-18 05:48:29
【问题描述】:

我需要获取我的安卓手机屏幕上特定点的颜色信息。

有没有办法通过亚行做到这一点?

我现在使用内置命令 screencap 来捕获整个屏幕,然后读取特定点的颜色。但是,它太慢了。

【问题讨论】:

    标签: android colors screen adb pixel


    【解决方案1】:

    我将发布我自己问题的答案。答案可能是设备指定的(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. 现在,使用ddhd 变得很简单。假设我想获得 (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 是我的答案。

    【讨论】:

    • 不错的解决方案,但是为什么我在手机末尾添加“| hd”时无法执行命令,但从adb.exe控制台执行时可以执行? “|hd”有什么作用?
    • hdhexdump 用于显示二进制数据。例如,您在文本文件中有“123”,而hd THE-FILE 得到31 32 33。你的命令是什么?
    • 你好,我不是很明白坐标,为什么$y乘以1200而不是1920?
    • 4b 73 61 ff 也翻译什么? RGB颜色?为什么是 4 个字节?
    • 回复我自己。依次是红、绿、蓝、阿尔法。
    【解决方案2】:

    如果您的手机已root,并且您知道其framebuffer 格式,则可以使用ddhd (hexdump) 直接从framebuffer 文件中获取像素表示:

    adb shell "dd if=/dev/graphics/fb0 bs=<bytes per pixel> count=1 skip=<pixel offset> 2>/dev/null | hd"
    

    通常是&lt;bytes per pixel&gt; = 4&lt;pixel offset&gt; = Y * width + X,但在您的手机上可能会有所不同。

    【讨论】:

    • 我输入adb shell "dd if=/dev/graphics/fb0 bs=4 count=1 skip=1000 2&gt;/dev/null | hd",它返回Usage: hd [-b base] [-c count] [-r delay] file。似乎“hd”是在我的 bash shell 而不是 adb shell 中执行的。我尝试以下方法:我所以
    • 很可能你没有root 所以dd 不会为hd 生成任何输出来处理
    • 我尝试以下操作:adb shell su dd if=/dev/graphics/fb0 bs=4 count=1 skip=1000 2&gt;/dev/null | hd 它返回类似于 00000000: 00 00 00 00 s 0 sum 0 的内容
    • 这 4 个字节 00 00 00 00 是您要查找的数据。
    • 我得到了C6 7A 25 62,如何将值更改为RGB?
    【解决方案3】:

    根据之前接受的答案,我编写了一个 SH 函数,能够计算缓冲区等,以便在我的手机上开箱即用。

    用法:

    GetColorAtPixel X Y
    

    要点: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?也许这会解决嵌入问题。
    猜你喜欢
    • 1970-01-01
    • 2015-02-08
    • 2017-08-17
    • 2013-07-05
    • 2014-04-08
    • 1970-01-01
    相关资源
    最近更新 更多