Правельно думаете, скорость падает существенно, а результат незначителен.Можно поставить максимальное сжатие, но сильно упадет скорость (я думаю)
Кроме того, в GDI не предусмотренна работа с PNG и JPEG.
VladUs сказал(а):А какже функция _GDIPlus_ImageSaveToFileEx() , которая и спользует функцию _GDIPlus_EncodersGetCLSID(), где можно задавать тип кодировки (.jpg, .png и т.д).
Вот так:если вы мне скажите, как получить сжатые данные в AutoIt без создания файла (потоком)
как получить сжатые данные в AutoIt без создания файла
asdf8 сказал(а):Мне кажется, что легче создать RAM-диск и на нем сохранять в png.
Func _GetScreenshot($iX = 0, $iY = 0, $iWidth = -1, $iHeight = -1)
Local $tBD, $tData, $tOut, $hBitmap, $hDesktop, $hSrcDC, $hDstDC, $hDstSv, $pBits, $Lenght
If $iWidth = -1 Then
$iWidth = @DesktopWidth
EndIf
If $iHeight = -1 Then
$iHeight = @DesktopHeight
EndIf
$tBD = DllStructCreate($tagBITMAPINFOHEADER & 'byte[' & ($iWidth * $iHeight * 2) & ']')
If @error Then
Return 0
EndIf
DllStructSetData($tBD, 'biSize', 40)
DllStructSetData($tBD, 'biWidth', $iWidth)
DllStructSetData($tBD, 'biHeight', -$iHeight)
DllStructSetData($tBD, 'biPlanes', 1)
DllStructSetData($tBD, 'biBitCount', 16)
DllStructSetData($tBD, 'biCompression', $BI_RGB)
$hBitmap = _WinAPI_CreateDIBSection(0, $tBD, $DIB_RGB_COLORS, $pBits)
$hDesktop = _WinAPI_GetDesktopWindow()
$hSrcDC = _WinAPI_GetDC($hDesktop)
$hDstDC = _WinAPI_CreateCompatibleDC($hSrcDC)
$hDstSv = _WinAPI_SelectObject($hDstDC, $hBitmap)
_WinAPI_BitBlt($hDstDC, $iX, $iY, $iWidth, $iHeight, $hSrcDC, $iX, $iY, $SRCCOPY)
_WinAPI_SelectObject($hDstDC, $hDstSv)
_WinAPI_ReleaseDC($hDesktop, $hSrcDC)
_WinAPI_DeleteDC($hDstDC)
_WinAPI_GetBitmapBits($hBitmap, $iWidth * $iHeight * 2, DllStructGetPtr($tBD) + 40)
_WinAPI_DeleteObject($hBitmap)
$Lenght = _WinAPI_LZNTCompress($tBD, $tData)
$tOut = DllStructCreate('dword;dword;byte[' & ($Lenght - Mod($Lenght, 4) + 4) & ']')
DllStructSetData($tOut, 1, DllStructGetSize($tOut))
DllStructSetData($tOut, 2, $Lenght)
DllStructSetData($tOut, 3, DllStructGetData($tData, 1))
Return Binary(DllStructGetData(DllStructCreate('byte[' & DllStructGetSize($tOut) & ']', DllStructGetPtr($tOut)), 1))
EndFunc ;==>_GetScreenshot
Буду рад если поделитись опытом в этом направлении...Мне кажется, что легче создать RAM-диск
Буду рад если поделитись опытом в этом направлении...
Во - первых, стандартных средств нетСтандартными средствами системы - пока не нашел как сделать (может плохо искал), гуглятся только сторонние приложения
#Include <GDIPlus.au3>
#Include <Memory.au3>
#Include <ScreenCapture.au3>
#Include <WinAPIEx.au3>
_GDIPlus_Startup()
$hScreen = _ScreenCapture_Capture()
$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hScreen)
_WinAPI_DeleteObject($hScreen)
$tEncoder = _WinAPI_GUIDFromString(_GDIPlus_EncodersGetCLSID('png'))
$pEncoder = DllStructGetPtr($tEncoder)
$pStream = _WinAPI_CreateStreamOnHGlobal(0)
_GDIPlus_ImageSaveToStream($hBitmap, $pStream, $pEncoder)
_GDIPlus_BitmapDispose($hBitmap)
$hMemory = _WinAPI_GetHGlobalFromStream($pStream)
$pMemory = _MemGlobalLock($hMemory)
$iSize = _MemGlobalSize($hMemory)
$tData = DllStructCreate('byte[' & $iSize & ']', $pMemory)
$bData = DllStructGetData($tData, 1)
_MemGlobalFree($hMemory)
FileWrite(@ScriptDir & '\screenshot.png', $bData)
_GDIPlus_Shutdown()
Func _GDIPlus_ImageSaveToStream($hImage, $pStream, $pEncoder, $pParams = 0)
Local $Ret = DllCall($ghGDIPDll, 'uint', 'GdipSaveImageToStream', 'ptr', $hImage, 'ptr', $pStream, 'ptr', $pEncoder, 'ptr', $pParams)
If (@error) Or ($Ret[0]) Then
Return SetError(@error, @extended, 0)
EndIf
Return 1
EndFunc ;==>_GDIPlus_ImageSaveToStream
#Include <GDIPlus.au3>
#Include <Memory.au3>
#Include <WinAPIEx.au3>
TCPStartup()
$Socket = TCPConnect(@IPAddress1, 33891)
If @error Then
Exit
EndIf
_GDIPlus_Startup()
Global $tEncoder = _WinAPI_GUIDFromString(_GDIPlus_EncodersGetCLSID('png'))
Global $pEncoder = DllStructGetPtr($tEncoder)
While 1
TCPSend($Socket, _GetScreenshot(0, 0, 800, 600))
If @error Then
ExitLoop
EndIf
Sleep(1000)
WEnd
_GDIPlus_Shutdown()
TCPShutdown()
Func _GetScreenshot($iX = 0, $iY = 0, $iWidth = -1, $iHeight = -1)
Local $hSrcDC, $hDstDC, $hDstSv, $hBitmap, $hDesktop, $hScreen, $hMemory, $pMemory, $pStream, $tOut, $pOut, $iSize
If $iWidth = -1 Then
$iWidth = @DesktopWidth
EndIf
If $iHeight = -1 Then
$iHeight = @DesktopHeight
EndIf
$hDesktop = _WinAPI_GetDesktopWindow()
$hSrcDC = _WinAPI_GetDC($hDesktop)
$hScreen = _WinAPI_CreateCompatibleBitmap($hSrcDC, $iWidth, $iHeight)
$hDstDC = _WinAPI_CreateCompatibleDC($hSrcDC)
$hDstSv = _WinAPI_SelectObject($hDstDC, $hScreen)
_WinAPI_BitBlt($hDstDC, $iX, $iY, $iWidth, $iHeight, $hSrcDC, $iX, $iY, $SRCCOPY)
_WinAPI_SelectObject($hDstDC, $hDstSv)
_WinAPI_ReleaseDC($hDesktop, $hSrcDC)
_WinAPI_DeleteDC($hDstDC)
$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hScreen)
_WinAPI_DeleteObject($hScreen)
$pStream = _WinAPI_CreateStreamOnHGlobal(0)
_GDIPlus_ImageSaveToStream($hBitmap, $pStream, $pEncoder)
_GDIPlus_BitmapDispose($hBitmap)
$hMemory = _WinAPI_GetHGlobalFromStream($pStream)
$pMemory = _MemGlobalLock($hMemory)
$iSize = _MemGlobalSize($hMemory)
$tOut = DllStructCreate('dword;dword;byte[' & ($iSize - Mod($iSize, 4) + 4) & ']')
$pOut = DllStructGetPtr($tOut)
DllStructSetData($tOut, 1, DllStructGetSize($tOut))
DllStructSetData($tOut, 2, $iSize)
_MemMoveMemory($pMemory, $pOut + 8, $iSize)
_MemGlobalFree($hMemory)
Return DllStructGetData(DllStructCreate('byte[' & DllStructGetSize($tOut) & ']', DllStructGetPtr($tOut)), 1)
EndFunc ;==>_GetScreenshot
Func _GDIPlus_ImageSaveToStream($hImage, $pStream, $pEncoder, $pParams = 0)
Local $Ret = DllCall($ghGDIPDll, 'uint', 'GdipSaveImageToStream', 'ptr', $hImage, 'ptr', $pStream, 'ptr', $pEncoder, 'ptr', $pParams)
If (@error) Or ($Ret[0]) Then
Return SetError(@error, @extended, 0)
EndIf
Return 1
EndFunc ;==>_GDIPlus_ImageSaveToStream
#Include <Constants.au3>
#Include <GDIPlus.au3>
#Include <Memory.au3>
#Include <WinAPIEx.au3>
Global Const $STM_SETIMAGE = 0x0172
Global Const $STM_GETIMAGE = 0x0173
TCPStartup()
$Main = TCPListen(@IPAddress1, 33891)
If @error Then
Exit
EndIf
GUICreate('MyGUI', 800, 600, @DesktopWidth - 819, @DesktopHeight - 671)
$Pic = GUICtrlCreatePic('', 0, 0, 800, 600)
GUISetState()
Do
$Socket = TCPAccept($Main)
Until $Socket <> -1
Global $tHeader = DllStructCreate('byte[4]')
Global $pHeader = DllStructGetPtr($tHeader)
Global $bData = 0, $Count = 0
_GDIPlus_Startup()
Do
If Not IsBinary($bData) Then
$bData = TCPRecv($Socket, 16384, 1)
If @error Then
ExitLoop
EndIf
EndIf
If IsBinary($bData) Then
If Not $Count Then
DllStructSetData($tHeader, 1, $bData)
$tData = DllStructCreate('dword', $pHeader)
$Size = DllStructGetData($tData, 1)
$tData = DllStructCreate('byte[' & $Size & ']')
$pData = DllStructGetPtr($tData)
EndIf
$Lenght = BinaryLen($bData)
$Sum = $Count + $Lenght
If $Sum > $Size Then
$dL = $Size - $Count
$tPart = DllStructCreate('byte[' & $dL & ']', $pData + $Count)
DllStructSetData($tPart, 1, $bData)
$tByte = DllStructCreate('byte[' & $Lenght & ']')
$tRecv = DllStructCreate('byte[' & ($Lenght - $dL) & ']', DllStructGetPtr($tByte) + $dL)
DllStructSetData($tByte, 1, $bData)
$bData = DllStructGetData($tRecv, 1)
$Sum = $Size
Else
$tPart = DllStructCreate('byte[' & $Lenght & ']', $pData + $Count)
DllStructSetData($tPart, 1, $bData)
$Count = $Sum
$bData = 0
EndIf
If $Sum = $Size Then
_SetScreenshot($Pic, $tData)
$Count = 0
EndIf
EndIf
Until GUIGetMsg() = -3
_GDIPlus_Shutdown()
TCPCloseSocket($Socket)
TCPShutdown()
Func _SetScreenshot($CtrlID, ByRef $tData, $fUpdate = 0)
Local $hBitmap, $hPrev, $hScreen, $hMemory, $pMemory, $pStream, $pData, $iSize
$hWnd = GUICtrlGetHandle($CtrlID)
If Not $hWnd Then
Return 0
EndIf
$pData = DllStructGetPtr($tData)
$iSize = DllStructGetData(DllStructCreate('dword', $pData + 4), 1)
$hMemory = _MemGlobalAlloc($iSize, $GMEM_MOVEABLE)
$pMemory = _MemGlobalLock($hMemory)
_MemMoveMemory($pData + 8, $pMemory, $iSize)
_MemGlobalUnlock($hMemory)
$pStream = _WinAPI_CreateStreamOnHGlobal($hMemory)
$hBitmap = _GDIPlus_BitmapCreateFromStream($pStream)
$hScreen = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
_GDIPlus_BitmapDispose($hBitmap)
_MemGlobalFree($hMemory)
_WinAPI_DeleteObject(_SendMessage($hWnd, $STM_SETIMAGE, $IMAGE_BITMAP, $hScreen))
$hPrev = _SendMessage($hWnd, $STM_GETIMAGE)
If $hPrev <> $hScreen Then
_WinAPI_DeleteObject($hScreen)
EndIf
If $fUpdate Then
_WinAPI_UpdateWindow($hWnd)
EndIf
Return 1
EndFunc ;==>_SetScreenshot
Func _GDIPlus_BitmapCreateFromStream($pStream)
Local $Ret = DllCall($ghGDIPDll, 'uint', 'GdipCreateBitmapFromStream', 'ptr', $pStream, 'ptr*', 0)
If (@error) Or ($Ret[0]) Then
Return SetError(@error, @extended, 0)
EndIf
Return $Ret[2]
EndFunc ;==>_GDIPlus_BitmapCreateFromStream
Мне кажется размер картинки 30 кб, для такого способа не получиться добиться.
Arei сказал(а):Извините,я не так выразился качество картинки,конечно же.