Что нового

Как сэмулировать создание скриншота

Автор
sforce5

sforce5

Олл фо ЛулзЪ
Сообщения
160
Репутация
41
CreatoR сказал(а):
sforce5 [?]
Проблема вот в этом:
Ясно. А если использовать Captdll, снимок захватывается как надо?

Нет, такая же фигня как и с _Screen_ScreenCapture.
Понравилась идея про получения сведений с экрана попиксельно, но как её воссоздать.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
sforce5 [?]
но как её воссоздать
ну, на самом деле, как сказал CreatoR это извращение. про скорость выполнения такого финта, я тоже ничего не знаю. т.к заткнулся на определенном шаге. поэтому, мне кажется что оптимальным будет все же Send({PRINTSCREEN}). Но, если же все хочешь воспользоваться этим, то тебе придется выяснить, как записывать бинарные данные в файл побайтово в случае когда данные - это числа. на данный момент пишется всегда по 4 байта.
Например, если я хочу записать бинарно число 5, то это должно быть 0x05. а в autoit получается 0x05000000. а со структурой я разобрался. после объявления спецификации и заголовков, цвета просто записываются в 16-ом виде в формате BGR


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

скорость считывания инфы для экрана с разрешением 1280х1024 заняло 25 сек. файл созданный из этой инфы по 6 символов на цвет (формат RRGGBB) с разделителем @TAB строк и @CRLF между строками занял 11 МБ. если кого-то это устраивает, то можно продолжить эксперименты :laugh:
 
Автор
sforce5

sforce5

Олл фо ЛулзЪ
Сообщения
160
Репутация
41
Kaster сказал(а):
CreatoR
очень странно видеть подобный совет разработчику, который является соавтором программы для снятия скриншотов, который собственно эту команду и использует ;D

Всмысле со-автором?
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Ну вот, как и обещал. Эксперименты со считыванием пикселей с экрана завершен. Скорость просто чудовищно маленькая.
Только боюсь все мои изыскания были попусту :laugh:
Т.к. PixelGetColor тоже не хватает overlay'ные окна :rofl:
Зато, для себя узнал много нового и интересного. В основном касаемо формата bmp
Код:
#include <WinAPI.au3>

Global $nBytes
Global $file = @ScriptDir & '\color.bmp'

$X1 = 200
$X2 = 300
$Y1 = 400
$Y2 = 500; Coordinates of upper left and bottom right vertices of recatangle to scan

_Header($X1, $X2, $Y1, $Y2)
_BMPFiller($X1, $X2, $Y1, $Y2)

Func _BMPFiller($X1, $X2, $Y1, $Y2)
	$tBuffer = DllStructCreate("byte[" & 3 & "]")
	$hFile = _WinAPI_CreateFile($file, 3)
	_WinAPI_SetFilePointer($hFile, 0, 2)
	For $j = $Y2 to $Y1 Step -1
		For $i = $X1 to $X2
			$data = Binary(PixelGetColor($i, $j))
			DllStructSetData($tBuffer, 1, $data)
			_WinAPI_WriteFile($hFile, DllStructGetPtr($tBuffer), 3, $nBytes)
		Next
		If Mod($w, 4) > 0 Then
			$tmp_buf = DllStructCreate("byte[" & Mod($w, 4) & "]")
			$zero = Binary(0)
			DllStructSetData($tmp_buf, 1, $zero)
			_WinAPI_WriteFile($hFile, DllStructGetPtr($tmp_buf), Mod($w, 4), $nBytes)
		EndIf
	Next
EndFunc

Func _Header($X1, $X2, $Y1, $Y2)
	Global $w = $X2 - $X1 + 1
	Global $h = $Y2 - $Y1 + 1
	$hWrite = FileOpen($file, 16 + 2)
	FileWrite($hWrite, 'BM'); 2 bytes - 1-2
	$imsize = ($w * 3 + Mod($w, 4)) * $h
	$size = $imsize + 54
	FileWrite($hWrite, Dec(Hex($size)));      	4 bytes - 3-6
	FileWrite($hWrite, 0x0);                 	2x2 bytes - 7-10
	FileWrite($hWrite, 0x36);                	4 bytes - 11-14
	FileWrite($hWrite, 40);                 	4 bytes - 15-18
	FileWrite($hWrite, Int($w));           		4 bytes - 19-22
	FileWrite($hWrite, Int($h));             	4 bytes - 23-26
	FileWrite($hWrite, Int(1572865));        	2x2 bytes; 2bytes - 1, 2 bytes-24; 27-30
	FileWrite($hWrite, Int(0));              	4 bytes - 31-34
	FileWrite($hWrite, Dec(Hex($imsize)));   		4 bytes - 35-38
	FileWrite($hWrite, 3780);               	4 bytes - 39-42
	FileWrite($hWrite, 3780);               	4 bytes - 43-46
	FileWrite($hWrite, Int(0));              	#########; 4 bytes of zeros - 47-50
	FileWrite($hWrite, Int(0));              	#########; 4 bytes of zeros - 50-54
	FileClose($hWrite)
EndFunc
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Kaster
Неплохо! :beer:

[?]
Скорость просто чудовищно маленькая
Её можно увеличить если вытащить наружу из цикла лишние вызовы функций.
Вот поправленная версия, плюс попытался реализовать захват фонового окна, методом использования параметра hWnd в PixelGetColor, однако оно почему то не работает, требует активности окна :(

Код:
#include <WinAPI.au3>

$sFile = @DesktopDir & '\Screen.bmp'

$X1 = 0
$X2 = 500
$Y1 = 0
$Y2 = 500

$hWnd = WinGetHandle("[CLASS:Progman]")

_ScreenCaptureToBMP($sFile, $X1, $X2, $Y1, $Y2, $hWnd)

ShellExecute($sFile)

Func _ScreenCaptureToBMP($sFile, $X1, $X2, $Y1, $Y2, $hWnd=0)
	Local $hFile, $iMSize, $iSize, $iW, $iH
	Local $stBuffer, $pBuffer, $iMod, $stMod_Buffer, $pMod_Buffer, $sData, $nBytes
	Local $iOld_Opt = -1
	Local $hKernel_Dll, $tWritten, $pWritten
	
	$iW = $X2 - $X1 + 1
	$iH = $Y2 - $Y1 + 1
	
	#Region BMP Header part
	$hFile = FileOpen($sFile, 16 + 2)
	FileWrite($hFile, 'BM'); 2 bytes - 1-2
	$iMSize = ($iW * 3 + Mod($iW, 4)) * $iH
	$iSize = $iMSize + 54
	FileWrite($hFile, Dec(Hex($iSize)));       4 bytes - 3-6
	FileWrite($hFile, 0x0);                    2x2 bytes - 7-10
	FileWrite($hFile, 0x36);                   4 bytes - 11-14
    FileWrite($hFile, 40);                     4 bytes - 15-18
    FileWrite($hFile, Int($iW));                4 bytes - 19-22
    FileWrite($hFile, Int($iH));                4 bytes - 23-26
    FileWrite($hFile, Int(1572865));           2x2 bytes; 2bytes - 1, 2 bytes-24; 27-30
    FileWrite($hFile, Int(0));                 4 bytes - 31-34
    FileWrite($hFile, Dec(Hex($iMSize)));          4 bytes - 35-38
    FileWrite($hFile, 3780);                   4 bytes - 39-42
    FileWrite($hFile, 3780);                   4 bytes - 43-46
    FileWrite($hFile, Int(0));                 #########; 4 bytes of zeros - 47-50
    FileWrite($hFile, Int(0));                 #########; 4 bytes of zeros - 50-54
    FileClose($hFile)
	#EndRegion BMP Header part
	;
	
	$hKernel_Dll = DllOpen("Kernel32.dll")
	
    $stBuffer = DllStructCreate("byte[3]")
	$pBuffer = DllStructGetPtr($stBuffer)
	
	$tWritten = DllStructCreate("int Written")
	$pWritten = DllStructGetPtr($tWritten)
	
	$hFile = _WinAPI_CreateFile($sFile, 3)
    _WinAPI_SetFilePointer($hFile, 0, 2)
	
	$iMod = Mod($iW, 4)
	
	If $iMod > 0 Then
		$stMod_Buffer = DllStructCreate("byte[" & $iMod & "]")
		DllStructSetData($stMod_Buffer, 1, Binary(0))
		$pMod_Buffer = DllStructGetPtr($stMod_Buffer)
	EndIf
	
	If IsHWnd($hWnd) Then
		$iOld_Opt = Opt("PixelCoordMode", 0)
	EndIf
	
    For $j = $Y2 To $Y1 Step -1
        For $i = $X1 To $X2
            $sData = Binary(PixelGetColor($i, $j, $hWnd))
            DllStructSetData($stBuffer, 1, $sData)
            _WinAPI_WriteFileEx($hFile, $pBuffer, 3, $nBytes, $tWritten, $pWritten, $hKernel_Dll)
        Next
		
        If $iMod > 0 Then
            _WinAPI_WriteFileEx($hFile, $pMod_Buffer, $iMod, $nBytes, $tWritten, $pWritten, $hKernel_Dll)
        EndIf
    Next
	
	DllClose($hKernel_Dll)
	_WinAPI_CloseHandle($hFile)
	If $iOld_Opt <> -1 Then Opt("PixelCoordMode", $iOld_Opt)
EndFunc

Func _WinAPI_WriteFileEx($hFile, $pBuffer, $iToWrite, ByRef $iWritten, $tWritten = 0, $pWritten = 0, $vKernel_Dll = 'Kernel32.dll')
	Local $aResult = DllCall($vKernel_Dll, "int", "WriteFile", "hwnd", $hFile, "ptr", $pBuffer, _
		"uint", $iToWrite, "ptr", $pWritten, "ptr", 0)
	$iWritten = DllStructGetData($tWritten, "Written")
	
	Return $aResult[0] <> 0
EndFunc


P.S
Кстати в последних бетах есть функия FileSetPos, возможно ею можно заменить WinAPI, что тоже может увеличить скорость обработки...
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
CreatoR
ну что сказать, как всегда круто ;)
понял, про вызов одного и того же вне цикла. упустил как-то этот момент.
а по поводу фонового окна, хорошо придумал. у меня захватил именно активное окно.
CreatoR [?]
Кстати в последних бетах есть функия FileSetPos
спасибо, поизучаю
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Kaster
Изменил немного пример, вроде ещё немного увеличина скорость ;)
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
CreatoR
да. чуток быстрее. на моей тачке 200х200 первым способом 5.2 с, вторым 3.6.
а зачем вот это?
Код:
$hWnd = WinGetHandle("[CLASS:Progman]")
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Kaster [?]
а зачем вот это?
Это заголовок рабочего стола, это попытка снять скриншот именно с него, а не с активных окон.
 
Верх