heavenm 发表于 2019-6-28 09:49:59

怎么样才能从加载的图片后台找色,没成功是啥原因?有大神懂不!

本帖最后由 heavenm 于 2019-6-28 09:52 编辑

根据这个帖子改的
http://www.autoitx.com/forum.php ... hlight=%BA%F3%CC%A8

我不需要截图,直接从图片文件找色就OK了

#include <GDIPlus.au3>
#include <screencapture.au3>
$a=LToArray(221+5,97+5)
MsgBox(0, '', $a)



Func LToArray($iWidth=-1,$iHeight = -1);成功则返回数组.失败返回0.
      ;定义子程序必须的变量
    Local $hBitmap, $BitmapData, $i_width, $i_height, $Scan0, $pixelData, $s_BMPData, $i_Stride
      ;初始化GDI+库
      _GDIPlus_Startup()
      ;如果调用函数时候没有指定宽和高, 则调用API获取宽和高.
      If $iWidth = -1 Then $iWidth = 226
    If $iHeight = -1 Then $iHeight = 102
      ;调用函数获取指定窗体的位图句柄.
;~         $hBMP = _WinCapture($hand, $iWidth, $iHeight)
      ;从位图句柄创建Bitmap对象
                $hBMP = _GDIPlus_BitmapCreateFromFile ( 'w.jpg' )

      $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
      ;如果未创建成功,则直接退出.未创建成功可能是因为无效的图形句柄
      If @error Then
                _GDIPlus_ShutDown ()
                              MsgBox(0, '', 123123)
                Return 0
      EndIf      
      ;获取位图句柄的宽和高.
      $i_width = _GDIPlus_ImageGetWidth($hBitmap)
      $i_height = _GDIPlus_ImageGetHeight($hBitmap)      
      ;锁定位图句柄中用于输入输出的部分. 将位图句柄中的数据格式格式化成24位的RGB格式.
    $BitmapData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $i_width, $i_height, $GDIP_ILMREAD, $GDIP_PXF24RGB)
      ;以下几句可能是BMP的数据格式, 我不懂. 这是大牛阿福给的
    $i_Stride = DllStructGetData($BitmapData, "Stride")
    $Scan0 = DllStructGetData($BitmapData, "Scan0")
    $pixelData = DllStructCreate("ubyte lData[" & (Abs($i_Stride) * $i_height) & "]", $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[$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)
      ;从该行中读出指定的那个坐标.
      $a_return[$x][$y]= StringMid($s,$x*6+1 ,6)
      ;BGR转RGB.
      $a_return[$x][$y]= "0x"&StringRight($a_return[$x][$y],2)&StringMid($a_return[$x][$y],2,2)&StringLeft($a_return[$x][$y],2)
      Return $a_return
EndFunc

heavenm 发表于 2019-6-28 10:04:02

找到原因了!
#include <GDIPlus.au3>
#include <screencapture.au3>
$a=LToArray(221+5,97+5)
MsgBox(0, '', $a)



Func LToArray($iWidth=-1,$iHeight = -1);成功则返回数组.失败返回0.
      ;定义子程序必须的变量
    Local $hBitmap, $BitmapData, $i_width, $i_height, $Scan0, $pixelData, $s_BMPData, $i_Stride
      ;初始化GDI+库
      _GDIPlus_Startup()
      ;如果调用函数时候没有指定宽和高, 则调用API获取宽和高.
      If $iWidth = -1 Then $iWidth = 226
    If $iHeight = -1 Then $iHeight = 102
      ;调用函数获取指定窗体的位图句柄.
;~         $hBMP = _WinCapture($hand, $iWidth, $iHeight)
      ;从位图句柄创建Bitmap对象

      $hBitmap = _GDIPlus_BitmapCreateFromFile ( 'w.jpg' )
      ;如果未创建成功,则直接退出.未创建成功可能是因为无效的图形句柄
      If @error Then
                _GDIPlus_ShutDown ()
                Return 0
      EndIf      
      ;获取位图句柄的宽和高.
      $i_width = _GDIPlus_ImageGetWidth($hBitmap)
      $i_height = _GDIPlus_ImageGetHeight($hBitmap)      
      ;锁定位图句柄中用于输入输出的部分. 将位图句柄中的数据格式格式化成24位的RGB格式.
    $BitmapData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $i_width, $i_height, $GDIP_ILMREAD, $GDIP_PXF24RGB)
      ;以下几句可能是BMP的数据格式, 我不懂. 这是大牛阿福给的
    $i_Stride = DllStructGetData($BitmapData, "Stride")
    $Scan0 = DllStructGetData($BitmapData, "Scan0")
    $pixelData = DllStructCreate("ubyte lData[" & (Abs($i_Stride) * $i_height) & "]", $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[$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)
      ;从该行中读出指定的那个坐标.
      $a_return[$x][$y]= StringMid($s,$x*6+1 ,6)
      ;BGR转RGB.
      $a_return[$x][$y]= "0x"&StringRight($a_return[$x][$y],2)&StringMid($a_return[$x][$y],2,2)&StringLeft($a_return[$x][$y],2)
      Return $a_return
EndFunc

heavenm 发表于 2019-6-28 10:05:06


      $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)这句不用了直接改成 _GDIPlus_BitmapCreateFromFile ( 'w.jpg' )

heavenm 发表于 2019-6-28 10:17:45

:face (17):可是取色的颜色完全不对啊

heavenm 发表于 2019-6-28 14:22:47

好的,我已经放弃了,颜色差到火星去了!

#include <GDIPlus.au3>
#include <screencapture.au3>
#include <Array.au3>
#include <GDIPlus.au3>

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>

$a = _bitmapGetColor(295, 295)
;~ _ArrayDisplay($a)
MsgBox(0, '', $a)



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

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

;~         $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
      ;如果未创建成功,则直接退出.未创建成功可能是因为无效的图形句柄
      If @error Then
                _GDIPlus_ShutDown ()
                Return 0
      EndIf      
      ;获取位图句柄的宽和高.
      $i_width = _GDIPlus_ImageGetWidth($hBitmap)
      $i_height = _GDIPlus_ImageGetHeight($hBitmap)      
      ;锁定位图句柄中用于输入输出的部分. 将位图句柄中的数据格式格式化成24位的RGB格式.
    $BitmapData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $i_width, $i_height, $GDIP_ILMREAD, $GDIP_PXF24RGB)
      ;以下几句可能是BMP的数据格式, 我不懂. 这是大牛阿福给的
    $i_Stride = DllStructGetData($BitmapData, "Stride")
    $Scan0 = DllStructGetData($BitmapData, "Scan0")
    $pixelData = DllStructCreate("ubyte lData[" & (Abs($i_Stride) * $i_height) & "]", $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[$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)
      ;从该行中读出指定的那个坐标.
      $a_return[$x][$y]= StringMid($s,$x*6+1 ,6)
      ;BGR转RGB.
      $a_return[$x][$y]= "0x"&StringRight($a_return[$x][$y],2)&StringMid($a_return[$x][$y],2,2)&StringLeft($a_return[$x][$y],2)
      Return $a_return
EndFunc   ;==>_bitmapGetColor

afan 发表于 2019-6-28 14:53:47

heavenm 发表于 2019-6-28 14:22
好的,我已经放弃了,颜色差到火星去了!

第59行改一下看看
$a_return[$x][$y]= "0x"&StringRight($a_return[$x][$y],2)&StringMid($a_return[$x][$y],3,2)&StringLeft($a_return[$x][$y],2)

heavenm 发表于 2019-6-29 09:15:08

本帖最后由 heavenm 于 2019-6-29 09:28 编辑

afan 发表于 2019-6-28 14:53
第59行改一下看看
$a_return[$x][$y]= "0x"&StringRight($a_return[$x][$y],2)&StringMid($a_return[$x] ...
诶!这是什么原理,我都准备放弃了,颜色好像完全正确了!好神奇

heavenm 发表于 2019-6-29 09:29:42

afan 发表于 2019-6-28 14:53
第59行改一下看看
$a_return[$x][$y]= "0x"&StringRight($a_return[$x][$y],2)&StringMid($a_return[$x] ...

太感谢了!我一直以为是图片问题!图片改了N次....

zghwelcome 发表于 2019-6-29 10:50:41

获取的颜色信息$s_BMPData,去掉0x后,每8字节一组,每组从左到右分别为:蓝、绿、红、透明度 (BBGGRRAA)

heavenm 发表于 2019-7-3 12:30:24

#include <GDIPlus.au3>
#include <screencapture.au3>
#include <Array.au3>
#include <GDIPlus.au3>

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
$hTimer = TimerInit()
$a = _bitmapGetColor('1.jpg',50, 50)
MsgBox(0,TimerDiff($hTimer), $a)



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

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

;~         $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] = "0x" & StringRight($a_return[$iX][$iY], 2) & StringMid($a_return[$iX][$iY], 3, 2) & StringLeft($a_return[$iX][$iY], 2)
      Return $a_return[$iX][$iY]
EndFunc   ;==>_bitmapGetColor

准确性100%,完美.坐标点完美匹配!

heavenm 发表于 2019-7-3 12:32:10

不过PS不知道是什么鬼,设置的颜色,和图片颜色不一样,保存的图片,用PS自己打开重新取色,颜色都不一样,这也太逗了!

tarcy118 发表于 2019-7-7 00:37:34

不错支持一下
页: [1]
查看完整版本: 怎么样才能从加载的图片后台找色,没成功是啥原因?有大神懂不!