Что нового

попиксельная перерисовка участка экрана сразу в GUI

running-frag

why me?
Сообщения
441
Репутация
60
задача вот какая есть окно с которого получаем данные (скрины), нужно перерисовать заданный участок скрина в GUI, при условии что мы после хотим выбирать опред. участок (уже в GUI) этого скрина

вот часть кода который получилось выудить, но переделать полностью пока не удаётся
Код:
#cs ----------------------------------------------------------------------------
	AutoIt Version: 3.3.6.1
#ce ----------------------------------------------------------------------------
Opt ("MustDeclareVars", 	1)
Opt ("MouseCoordMode",		2)
Opt ("PixelCoordMode",		2)



#Include <WinAPIEx.au3>
#Include <WindowsConstants.au3>

Local $iX = 300
Local $iY = 300

HotKeySet('{ESC}', '_Quit')

Local $hAction
Local $hGUI = 		GUICreate ("detector", 300, 300)	; main gui
Local $hExpand = 	GUICtrlCreateLabel ("", 100, 100)	; zone for rewrite image

Local $hForm = 		GUICreate ("", 200, 200, -1, -1, BitOR ($WS_DISABLED, $WS_POPUPWINDOW), BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST), $hGUI);old
					GUISetState(@SW_SHOW, $hForm)
					;GUISetState(@SW_SHOW, $hGUI)

While 1
    $hAction = GUIGetMsg ()
	
    _Capture($iX, $iY, 50, 50)
    Sleep(1)
WEnd

Func _Capture($iX, $iY, $iWidth, $iHeight)

    Local $tRect, $hDC, $hMemDC, $hBitmap, $hScreenshort

    $hScreenshort = _ScreenCapture($iX, $iY, $iWidth, $iHeight)
    $hBitmap = _WinAPI_ResizeBitmap($hScreenshort, 200, 200)
    _WinAPI_DeleteObject($hScreenshort)
    $hDC = _WinAPI_GetDC($hForm)
    $hMemDC = _WinAPI_CreateCompatibleDC($hDC)
    _WinAPI_SelectObject($hMemDC, $hBitmap)
    _WinAPI_SelectObject($hMemDC, _WinAPI_GetStockObject($NULL_BRUSH))
    _WinAPI_SelectObject($hMemDC, _WinAPI_GetStockObject($DC_PEN))
    _WinAPI_SetDCPenColor($hMemDC, 0xA00000)
    $tRect = _WinAPI_CreateRect(0, 0, 200, 200)
    _WinAPI_Rectangle($hMemDC, $tRect)
    _WinAPI_ReleaseDC($hForm, $hDC)
    _WinAPI_DeleteDC($hMemDC)
    _SetBitmap($hForm, $hBitmap, 255)
    _WinAPI_DeleteObject($hBitmap)
EndFunc   ;==>_Capture

Func _Quit()
    Exit
EndFunc   ;==>_Quit

Func _ScreenCapture($iX, $iY, $iWidth, $iHeight)

    Local $hWnd, $hDC, $hMemDC, $hBitmap

    $hWnd = _WinAPI_GetDesktopWindow()
    $hDC = _WinAPI_GetDC($hWnd)
    $hMemDC = _WinAPI_CreateCompatibleDC($hDC)
    $hBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iWidth, $iHeight)
    _WinAPI_SelectObject($hMemDC, $hBitmap)
    _WinAPI_BitBlt($hMemDC, 0, 0, $iWidth, $iHeight, $hDC, $iX, $iY, $SRCCOPY)
    _WinAPI_ReleaseDC($hWnd, $hDC)
    _WinAPI_DeleteDC($hMemDC)
    Return $hBitmap
EndFunc   ;==>_ScreenCapture

Func _SetBitmap($hWnd, $hBitmap, $iOpacity)

    Local $hDC, $hMemDC, $hSv, $pBlend, $tBlend, $pSize, $tSize, $pSource, $tSource

    $hDC = _WinAPI_GetDC($hWnd)
    $hMemDC = _WinAPI_CreateCompatibleDC($hDC)
    $hSv = _WinAPI_SelectObject($hMemDC, $hBitmap)
    $tSize = _WinAPI_GetBitmapDimension($hBitmap)
    $pSize = DllStructGetPtr($tSize)
    $tSource = DllStructCreate($tagPOINT)
    $pSource = DllStructGetPtr($tSource)
    $tBlend = DllStructCreate($tagBLENDFUNCTION)
    $pBlend = DllStructGetPtr($tBlend)
    DllStructSetData($tBlend, 'Alpha', $iOpacity)
    DllStructSetData($tBlend, 'Format', 0)
    _WinAPI_UpdateLayeredWindow($hWnd, $hDC, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA)
    _WinAPI_ReleaseDC($hWnd, $hDC)
    _WinAPI_SelectObject($hMemDC, $hSv)
    _WinAPI_DeleteDC($hMemDC)
EndFunc   ;==>_SetBitmap


Так же хочется что бы отображалось (перерисовывалось) в сетке (пример)


ps: изначально код был из "экранной лупы"


Добавлено:
Сообщение автоматически объединено:

Покурил немного. Выводить можно так.
Код:
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>

Opt ('MustDeclareVars', 1)

Local $iRw = 15 ; cell width
Local $iRh = 15 ; cell height

Local $iCw = 20 ; count cell width
Local $iCh = 9 	; count cell height

Local $sColor
Local $hAction
Local $hGUI = 	GUICreate ("My Draw")

Local $hTable = GUICtrlCreateGraphic	(10, 10, $iCw *($iRw -1), $iCh *($iRh -1), 0)
				GUICtrlSetBkColor		($hTable, 0xFFFFFF)
	
For $y = 0 To $iCh -1

	For $x = 0 To $iCw -1
				GUICtrlSetGraphic		($hTable, $GUI_GR_RECT, 	$x *($iRw -1), 		$y *($iRh -1), $iRw, $iRh)
			
		If $sColor == "color" Then
				GUICtrlSetGraphic		($hTable, $GUI_GR_COLOR, 	0xFFFFFF)
		Else
				GUICtrlSetGraphic		($hTable, $GUI_GR_COLOR, 	0x000000)
		EndIf
	
	Next
			
Next
				GUISetState (@SW_SHOW, $hGUI)

While True
	$hAction = GUIGetMsg ()
	
	Select
		Case $hAction = $GUI_EVENT_CLOSE
			ExitLoop
			
			
		EndSelect
	
WEnd

Нужна помощь в создании массива который будет пропускаться через цикл "заливая" нужный двадраты нужным цветом.
 
Автор
R

running-frag

why me?
Сообщения
441
Репутация
60
Так что есть у кого какие мысли на этот счёт? :(


Добавлено:
Сообщение автоматически объединено:

Код:
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>

Opt ("MustDeclareVars", 1)

#include <GUIConstants.au3>
#include <GDIPlus.au3>
#Include <WinAPI.au3>
#include <GUIStatusBar.au3>
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StatusBarConstants.au3>
#include <WindowsConstants.au3>
#include <Array.au3>


Func _imageToArray ($sFile)
	
					_GDIPlus_Startup ()
	Local $hIMG =	_GDIPlus_ImageLoadFromFile 	($sFile)
	Local $iW =		_GDIPlus_ImageGetWidth 		($hIMG)
	Local $iH = 	_GDIPlus_ImageGetHeight 	($hIMG)
	Local $_strct = _GDIPlus_BitmapLockBits 	($hIMG, 0, 0, $iW, $iH, $GDIP_ILMREAD, $GDIP_PXF32ARGB)
	
	Local $_width = 	DllStructGetData ($_strct, "width")
    Local $_height = 	DllStructGetData ($_strct, "height")
    Local $_stride = 	DllStructGetData ($_strct, "stride")
    Local $_format = 	DllStructGetData ($_strct, "format")
    Local $_Scan0 = 	DllStructGetData ($_strct, "Scan0")
	Local $_buffer
	
	Dim $aArray[$_width +1][$_height]
	
	$aArray[0][1] = $_width
	$aArray[0][2] = $_height
	
	For $x = 0 To $iW -1
		For $y = 0 To $iH -1
			$_buffer = DllStructCreate ("dword", $_Scan0 + ($y * $_stride) + ($x * 4))
			$aArray[$x +1][$y] = "0x"& Hex (DllStructGetData ($_buffer, 1), 6)
		Next
	Next
					_GDIPlus_BitmapUnlockBits ($hIMG, $_strct)
					_GDIPlus_ImageDispose ($hIMG)
					_GDIPlus_Shutdown ()
						
	Return $aArray
EndFunc

Func _getScreenImage ($sTitle, $iX = 0, $iY = 0, $iW = 100, $iH = 100)
	Local $hWND = 	WinGetHandle 	($sTitle)
					WinActivate 	($sTitle)
					WinWaitActive 	($sTitle)
					
					_GDIPlus_StartUp()

	Local $hGDC = 	_WinAPI_GetDC ($hWND)
	Local $hCDC = 	_WinAPI_CreateCompatibleDC ($hGDC)
	Local $hBMP = 	_WinAPI_CreateCompatibleBitmap ($hGDC, $iW, $iH)
					_WinAPI_SelectObject ($hCDC, $hBMP)
					_WinAPI_BitBlt ($hCDC, 0, 0, $iW, $iH, $hGDC, $iX, $iY, $SRCCOPY)
	
	Local $hIMG = 	_GDIPlus_BitmapCreateFromHBITMAP ($hBMP)
					_GDIPlus_ImageSaveToFile ($hIMG, "screen.bmp")
					_GDIPlus_ImageDispose ($hIMG)
					
					_WinAPI_ReleaseDC ($hWND, $hGDC)
					_WinAPI_DeleteDC ($hCDC)
					_WinAPI_DeleteObject ($hBMP)

					_GDIPlus_ShutDown()
EndFunc

Local $sColor
Local $hAction
Local $hGUI = 		GUICreate ("My Draw", 1000, 600)
Local $hBtnScr = 	GUICtrlCreateButton ("get screen", 1, 1)
Local $hBtnClr = 	GUICtrlCreateButton ("clear", 100, 1)
					GUISetState (@SW_SHOW, $hGUI)
					
					
Func loadImage ($aImage, $iCell = 5)
	Local $sCellColor = ""
	Global $hTable = 	GUICtrlCreateGraphic	(10, 50, $aImage[0][1] *($iCell -1), $aImage[0][2] *($iCell -1), $SS_WHITEFRAME)	

	For $y = 1 To $aImage[0][1] -1
		For $x = 1 To $aImage[0][2] -1
			$sCellColor = $aImage[$x][$y]
			
						GUICtrlSetGraphic		($hTable, $GUI_GR_COLOR, $GUI_GR_NOBKCOLOR, $sCellColor)
						GUICtrlSetGraphic		($hTable, $GUI_GR_RECT, $x *($iCell -1), $y *($iCell -1), $iCell, $iCell)
		Next
	Next
	
EndFunc

While True
	$hAction = GUIGetMsg ()
	
	Select
		Case $hAction = $GUI_EVENT_CLOSE
			ExitLoop
		
		Case $hAction = $hBtnScr
			loadImage (_imageToArray ("screen.bmp"), 5)
		
		Case $hAction = $hBtnClr
			GUICtrlDelete ($hTable)
			
		EndSelect
	
WEnd


Текущие косяки.
1. Не прорисовует с первого раза. Почему то начинает показывать только при втором вызове функции хотя рамка прорисовуется с первого вызова.
2. Безумные тормоза при попытке "потягать" окно. Такое впечатление как будто функция выполняется постоянно (функция прорисовки).

Какие есть ещё варианты или как избежать траблы описанные выше?

PS: положите любую картинку рядом с файлом с именем "screen.bmp"
 
Верх