找回密码
 加入
搜索
查看: 11298|回复: 38

[AU3基础] 还是图片取色的问题,有句代码看不懂是啥意思

[复制链接]
发表于 2019-8-5 20:41:02 | 显示全部楼层 |阅读模式
本帖最后由 heavenm 于 2019-8-5 20:42 编辑
#include <GDIPlus.au3>
#include <String.au3>
#include <Array.au3>

$FileErrPNG = FileRead(FileOpen('test.png', 16))
MsgBox(0, '', _bitmapGetColor($FileErrPNG, 9,9))



Func _bitmapGetColor($_hBitmap, $_iX, $_iY) ;成功则返回数组.失败返回0.
        Local $__begin_time = TimerInit()
        ;定义子程序必须的变量
        Local $BitmapData, $Scan0, $pixelData, $s_BMPData, $i_Stride
        ;初始化GDI+库
        _GDIPlus_Startup()
        ;如果调用函数时候没有指定宽和高, 则调用API获取宽和高.

        ;调用函数获取指定窗体的位图句柄.
;~         $hBMP = _WinCapture($hand, $iWidth, $iHeight)
        ;从位图句柄创建Bitmap对象
        $_hBitmap = _GDIPlus_BitmapCreateFromMemory($_hBitmap)
;~         $hBitmap = _GDIPlus_BitmapCreateFromFile($hBitmap)

;~         $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
        ;如果未创建成功,则直接退出.未创建成功可能是因为无效的图形句柄
        If @error Then
                _GDIPlus_Shutdown()
                Return 0
        EndIf
        ;获取位图句柄的宽和高.
        $iWidth = $_iX + 5
        $iHeight = $_iY + 5
        ;锁定位图句柄中用于输入输出的部分. 将位图句柄中的数据格式格式化成24位的RGB格式.
        $BitmapData = _GDIPlus_BitmapLockBits($_hBitmap, 0, 0, $_iX, $_iY, $GDIP_ILMREAD, $GDIP_PXF24RGB)
        ;以下几句可能是BMP的数据格式, 我不懂. 这是大牛阿福给的
        $i_Stride = DllStructGetData($BitmapData, "Stride")
        $Scan0 = DllStructGetData($BitmapData, "Scan0")
        $pixelData = DllStructCreate("ubyte lData[" & (Abs($i_Stride) * $iHeight) & "]", $Scan0)
        $s_BMPData = DllStructGetData($pixelData, "lData")
        $s_BMPData = StringTrimLeft($s_BMPData, 2)
        ;解锁BMP位图数据区块.
        _GDIPlus_BitmapUnlockBits($_hBitmap, $BitmapData)
        ;销毁位图句柄
        _GDIPlus_ImageDispose($_hBitmap)
        ;删除位图对象.
        _WinAPI_DeleteObject($_hBitmap)
        ;关闭GDI库
        _GDIPlus_Shutdown()
        ;定义变量.
        Local $a_return[$iWidth][$iHeight], $s
        ;从位图数据中取出指定的那行.
;~         Local $a_return[$i_width][$i_height], $x = $i_width - 5, $y = $i_height - 5, $s
;~         $s = StringMid($s_BMPData, $y * ($i_Stride * 2) + 1, $i_width * 6)
        $s = StringMid($s_BMPData, $_iY * ($i_Stride * 2) + 1, $iWidth * 6)

        ;从该行中读出指定的那个坐标.
        $a_return[$_iX][$_iY] = StringMid($s, $_iX * 6 + 1, 6)
        ;BGR转RGB.
        $a_return[$_iX][$_iY] = StringRight($a_return[$_iX][$_iY], 2) & StringMid($a_return[$_iX][$_iY], 3, 2) & StringLeft($a_return[$_iX][$_iY], 2)
        
        ConsoleWrite(StringFormat('%s ][ %s \n', '_bitmapGetColor', TimerDiff($__begin_time)))
        Return StringLower($a_return[$_iX][$_iY])
EndFunc   ;==>_bitmapGetColor

我想实现把所有的颜色都写到数组里面,现在的代码只会把指定坐标的颜色输出
有些代码看不懂,比如这句
$_iY * ($i_Stride * 2) + 1

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2019-8-5 22:09:39 | 显示全部楼层
游客,如果您要查看本帖隐藏内容请回复

评分

参与人数 1金钱 +80 贡献 +20 收起 理由
heavenm + 80 + 20 厉害了

查看全部评分

发表于 2019-8-6 22:00:37 | 显示全部楼层
heavenm 发表于 2019-8-6 20:52
_GDIPlus_BitmapLockBits 的X,Y值可以定位起始坐标,
矩形宽度和高度是定义不了的,怎么取值都会按顺序来读 ...

还是有用的,只是这里用处不大,帮你改了部分,试下
#include <GDIPlus.au3>

Local $sImageFile = @ScriptDir & '\6x6.png'
;~ Global $aAryImage = _BitmapGetColorToArray($sImageFile, '[0,0][6,6]')
Global $aAryImage = _BitmapGetColorToArray($sImageFile, '[1,1][4,4]')

$Form1 = GUICreate('Form1', 600, 600)
For $i = 0 To UBound($aAryImage) - 1;行
        For $x = 0 To UBound($aAryImage, 2) - 1
                $Label1 = GUICtrlCreateLabel($aAryImage[$i][$x], $x * 82, $i * 82, 80, 80)
                GUICtrlSetBkColor(-1, '0x' & $aAryImage[$i][$x])
                GUICtrlSetColor(-1, 0xffffff)
        Next
Next
GUISetState()
While GUIGetMsg() <> -3
WEnd

Func _BitmapGetColorToArray($__hBitmap, $__coordinate)
        Local $__begin_time = TimerInit()
        $__coordinate = StringRegExp($__coordinate, '\[(.+?)\]', 3)
        Local $__posi = StringSplit($__coordinate[0], ',', 2)
        Local $__size = StringSplit($__coordinate[1], ',', 2)

        _GDIPlus_Startup()
        Local $hImage = _GDIPlus_ImageLoadFromFile($__hBitmap)
        If @error Then
                _GDIPlus_Shutdown()
                Return SetError(1)
        EndIf

        Local $i_Width = _GDIPlus_ImageGetWidth($hImage)
        Local $i_Height = _GDIPlus_ImageGetHeight($hImage)
        Local $__x = $__posi[0]
        Local $__y = $__posi[1]
        Local $iIW = $__size[0] - $__posi[0]
        Local $iIH = $__size[1] - $__posi[1]
        ConsoleWrite(StringFormat('%s ][ x=%s y=%s w=%s h=%s \n', '_bitmapGetColor', $__x, $__y, $iIW, $iIH))

        Local $tBitmapData = _GDIPlus_BitmapLockBits($hImage, $__x, $__y, 1, 1, $GDIP_ILMREAD, $GDIP_PXF32ARGB)
        Local $Scan0 = DllStructGetData($tBitmapData, 'Scan0')
        Local $v_BufferA = DllStructCreate('byte[' & $i_Width * $i_Height * 4 & ']', $Scan0)
        Local $sAllPixels = DllStructGetData($v_BufferA, 1)
        $v_BufferA = 0
        _GDIPlus_BitmapUnlockBits($hImage, $tBitmapData)
        _GDIPlus_ImageDispose($hImage)
        _GDIPlus_Shutdown()

        $sAllPixels = StringTrimLeft($sAllPixels, 2)
        $sAllPixels = StringRegExpReplace($sAllPixels, '(..)(..)(..)(..)', '${3}${2}${1}')
        $sAllPixels = StringMid($sAllPixels, 1, $i_Width * 6 * $iIH)
        $sAllPixels = StringRegExpReplace($sAllPixels, '(.{' & $i_Width * 6 & '})', '${1}' & @CRLF)
        $sAllPixels = StringRegExpReplace($sAllPixels, '(?m)^(.{' & $iIW * 6 & '}).*\v+', '${1}')
        Local $aReg = StringRegExp($sAllPixels, '(.{6})', 3)
        If @error Then Return SetError(2)
        If UBound($aReg) <> $iIH * $iIW Then Return SetError(4)
        Local $aRet[$iIH][$iIW], $h = 0, $w = 0
        For $i = 0 To UBound($aReg) - 1
                $aRet[$h][$w] = $aReg[$i]
                $w += 1
                If $w > $iIW - 1 Then
                        $w = 0
                        $h += 1
                EndIf
        Next
        ReDim $aReg[0]
        $aReg = 0
        ConsoleWrite(StringFormat('%s ][ %s \n', '_bitmapGetColor', TimerDiff($__begin_time)))
        Return $aRet
EndFunc   ;==>_BitmapGetColorToArray
发表于 2019-8-5 22:04:02 | 显示全部楼层
你确定你取的对应坐标的颜色值对吗
 楼主| 发表于 2019-8-5 22:59:08 | 显示全部楼层
zghwelcome 发表于 2019-8-5 22:09
**** 本内容被作者隐藏 ****

完美!高手啊,你竟然看懂这个
我看不懂的那段,你都直接去掉了,我还在学习上一段代码呢!

等我再理解一下你的代码!一脸懵逼啊!
 楼主| 发表于 2019-8-5 23:20:48 | 显示全部楼层
现在论坛很厉害啊!以前我提的问题基本上都是自问自答,现在竟然有人回答,感动到流泪!
 楼主| 发表于 2019-8-5 23:40:05 | 显示全部楼层
本帖最后由 heavenm 于 2019-8-5 23:42 编辑
zghwelcome 发表于 2019-8-5 22:09
**** 本内容被作者隐藏 ****

我主要想实现,某个区域范围内的图片随机抓取色点,对比画面是否在指定界面,抓取的色点最好颜色不要同一种

坐标点格式是[0,66][103,189],[顶部,左距,底部下,底部右],(用uiautomatorviewer读取出来的)


高手能直接帮我改出成品不,请你抽包烟
没想到会有人回答,我以为得自问自答呢!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
 楼主| 发表于 2019-8-5 23:46:20 | 显示全部楼层
本来我手工抓色点的,结果发现每部不一样的手机,色点位置都不一样,直接懵逼了,每个不同的手机要抓一次色点,好麻烦!
所以想弄个自动抓取色点,然后在对比
发表于 2019-8-6 13:15:31 | 显示全部楼层
你的项目太高深,我搞不懂啊
 楼主| 发表于 2019-8-6 16:11:18 | 显示全部楼层
zghwelcome 发表于 2019-8-6 13:15
你的项目太高深,我搞不懂啊

没事没事,我自己改改,最关键的部分你已经帮我完成了!3Q
 楼主| 发表于 2019-8-6 19:59:23 | 显示全部楼层
和图片像素一样结果是正确的,如果只截取部分,就不对了!
#include <GDIPlus.au3>
#include <String.au3>
#include <Array.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
Local $sImageFile = @ScriptDir & '\6x6.png'
Global $aAryImage = _BitmapGetColorToArray($sImageFile, '[0,0][6,6]')
;~ If Not @error Then _ArrayDisplay($aAryImage)

$Form1 = GUICreate("Form1", 600, 600)
For $i = 0 To UBound($aAryImage) - 1;行
        For $x=0 To UBound($aAryImage, 2) - 1
                $Label1 = GUICtrlCreateLabel($aAryImage[$i][$x], $x * 82,  $i* 82, 80, 80)
                GUICtrlSetBkColor(-1, '0x' & $aAryImage[$i][$x])
                GUICtrlSetColor (-1, 0xffffff )
        Next
Next

GUISetState(@SW_SHOW)
While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
                Case $GUI_EVENT_CLOSE
                        Exit

        EndSwitch
WEnd

;~ MsgBox(0, '', _bitmapGetColor($FileErrPNG, 1, 1))
Func _BitmapGetColorToArray($__hBitmap, $__coordinate)
        Local $__begin_time = TimerInit()
        $__coordinate = _StringBetween($__coordinate, '[', ']');坐标组
        $__posi = StringSplit($__coordinate[0], ',', 2)
        $__size = StringSplit($__coordinate[1], ',', 2)
        
        _GDIPlus_Startup()
        Local $hImage = _GDIPlus_ImageLoadFromFile($__hBitmap)
        If @error Then
                _GDIPlus_Shutdown()
                Return SetError(1)
        EndIf
        Local $Scan0, $iIW, $iIH, $aReg
        Local $v_BufferA, $sAllPixels,  $tBitmapData
;~         $iIW = _GDIPlus_ImageGetWidth($hImage)
;~         $iIH = _GDIPlus_ImageGetHeight($hImage)
        $__x = $__posi[0]
        $__y = $__posi[1]
        $iIW = $__size[0] - $__posi[0]
        $iIH = $__size[1] - $__posi[1]
        ConsoleWrite(StringFormat('%s ][ x=%s y=%s w=%s h=%s \n', '_bitmapGetColor', $__x, $__y, $iIW, $iIH))

        $tBitmapData = _GDIPlus_BitmapLockBits($hImage, $__x, $__y, $iIW, $iIH, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB)
        $Scan0 = DllStructGetData($tBitmapData, "Scan0")
        $v_BufferA = DllStructCreate("byte[" & $iIH * $iIW * 4 & "]", $Scan0)
        $sAllPixels = DllStructGetData($v_BufferA, 1)
        $v_BufferA = 0
        _GDIPlus_BitmapUnlockBits($hImage, $tBitmapData)
        _GDIPlus_ImageDispose($hImage)
        _GDIPlus_Shutdown()

        $sAllPixels = StringTrimLeft($sAllPixels, 2)
        $sAllPixels = StringRegExpReplace($sAllPixels, "(.{2})(.{2})(.{2})(.{2})", "${3}${2}${1}")
        $aReg = StringRegExp($sAllPixels, '(.{6})', 3)
        If @error Then Return SetError(2)
        If UBound($aReg) <> $iIH * $iIW Then Return SetError(4)
        Local $aRet[$iIH][$iIW], $h = 0, $w = 0
        For $i = 0 To UBound($aReg) - 1
                $aRet[$h][$w] = $aReg[$i]
                $w += 1
                If $w > $iIW - 1 Then
                        $w = 0
                        $h += 1
                EndIf
        Next
        ReDim $aReg[0]
        $aReg = 0
        ConsoleWrite(StringFormat('%s ][ %s \n', '_bitmapGetColor', TimerDiff($__begin_time)))
        Return $aRet
EndFunc   ;==>_BitmapGetColorToArray

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
 楼主| 发表于 2019-8-6 20:12:33 | 显示全部楼层
我看说明_GDIPlus_BitmapLockBits写得是读取部分位图啊,咋不行呢!
 楼主| 发表于 2019-8-6 20:52:56 | 显示全部楼层
_GDIPlus_BitmapLockBits 的X,Y值可以定位起始坐标,
矩形宽度和高度是定义不了的,怎么取值都会按顺序来读取,并不会按矩形来读取图片内容!
,好吧!换个方法,是我呆了,我发现这句根本没用!
 楼主| 发表于 2019-8-7 02:32:13 | 显示全部楼层
afan 发表于 2019-8-6 22:00
还是有用的,只是这里用处不大,帮你改了部分,试下

咦!感觉好像是这样子!我明天研究研究!我去,我都准备放弃了,受到鼓励!!感谢
快快留个联系方式,我请你喝奶茶!
 楼主| 发表于 2019-8-7 09:46:06 | 显示全部楼层
本帖最后由 heavenm 于 2019-8-7 09:47 编辑

比较大的图片,如果 x,y 不为0 AU3会崩溃

Global $aAryImage = _BitmapGetColorToArray($sImageFile, '[0,66][103,189]')

Local $sAllPixels = DllStructGetData($v_BufferA, 1)在这一句挂掉了

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-11-16 10:30 , Processed in 0.085739 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表