PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Как поместить снимок экрана в память?


Как поместить снимок экрана в память?

Сообщений 1 страница 20 из 20

1

Здравствуйте!
Как сделать скриншот сразу в память машины, минуя функции StartDrawing и StopDrawing()

Код:
CreateImage(1, WindowWidth(2), WindowHeight(2))
hwnd = OpenWindow(2, 0, 0, 300, 300, "ScreenShotWindow", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #WS_EX_LAYERED)
 HDC = GetDC_(hwnd)
          DC = StartDrawing(ImageOutput(1))
          BitBlt_(DC, 0, 0, WindowWidth(2), WindowHeight(2) , GetDC_(GetDesktopWindow_()), WindowX(2) + 3, WindowY(2) + 31, #SRCCOPY)
StopDrawing()
ReleaseDC_(0, HDC)

Я пишу функцию для автокликера, которая должна отслеживать графические изменения экрана или заданной экранной области.
(в заданной области начались графические изменения или изменения в заданной области закончились). Само собой, функция должна работать очень быстро, а циклическое применение  StartDrawing и StopDrawing() сильно замедляет процесс.
Подскажите, пожалуйста.

0

2

Видимо никому не интересно. Вам остаётся самостоятельно напрягать мозги тестируя функции. BitBlt копирует из одного DC в другое DC, не понятен смысл этого действия. GetDC_(hwnd) - зачем получать DC чтобы туда копировать. GetDC_(0) наверно получит DC экрана, потом нужно из объекта DC получить указатель на bitmap данные, вроде была такая функция WINAPI чтобы получить указатель bitmap. Самая лучшая позиция когда никто не помогает - гуглить, типа получить hbitmap и смотреть что он из себя представляет, если возможность с него сохранить в файл, если есть значит это данные в памяти и надо просто их использовать.

0

3

Nigri_lupus написал(а):

Как сделать скриншот сразу в память машины, минуя функции StartDrawing и StopDrawing()

Основное время выполняется BitBlt, а не StartDrawing и StopDrawing.

Код:
hwnd = OpenWindow(2, 0, 0, 300, 300, "ScreenShotWindow", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #WS_EX_LAYERED)
CreateImage(1, WindowWidth(2), WindowHeight(2))
HDC = GetDC_(hwnd)
Time = ElapsedMilliseconds()
DC = StartDrawing(ImageOutput(1))

For i=1 To 100
  BitBlt_(DC, 0, 0, WindowWidth(2), WindowHeight(2) , GetDC_(GetDesktopWindow_()), WindowX(2) + 3, WindowY(2) + 31, #SRCCOPY)
Next

StopDrawing()
Time = ElapsedMilliseconds()-Time
MessageRequester("",Str(Time))


Time = ElapsedMilliseconds()

For i=1 To 100
  DC = StartDrawing(ImageOutput(1))
  BitBlt_(DC, 0, 0, WindowWidth(2), WindowHeight(2) , GetDC_(GetDesktopWindow_()), WindowX(2) + 3, WindowY(2) + 31, #SRCCOPY)
  StopDrawing()
Next

Time = ElapsedMilliseconds()-Time
MessageRequester("",Str(Time))


ReleaseDC_(0, HDC)

0

4

Посмотри функции:
CreateCompatibleBitmap_(hDC, Width, Height)
GetDIBits_(...)
GdipCreateHBITMAPFromBitmap
GdipCreateBitmapFromHBITMAP
GdipCreateBitmapFromGraphics

Отредактировано AZJIO (12.05.2023 06:57:42)

0

5

Чтобы было быстро, нужно BitBlt делать не из одного окна в другое, а из окна в память Memory DC.
Таким образом будут исключены избыточная прорисовка и постоянный захват и освобождение HDC.

0

6

Чтобы создать контекст устройства в памяти, нужно вызвать функцию CreateCompatibleDC.
Однако с этим контекстом есть проблема: в нём выбрано чёрно‐белое изображение 1 на 1 пиксель. Чтобы это исправить, необходимо выбрать в этот контекст цветной BITMAP. Создать такой цветной BITMAP можно функцией CreateCompatibleBitmap.
После выбираем на этот MemoryDC наш цветной BITMAP функцией SelectObject.

Теперь можно делать BitBlt из DC экрана в DC памяти.

Вот и всё.

0

7

Замабувараев написал(а):

Чтобы было быстро, нужно BitBlt делать не из одного окна в другое, а из окна в память Memory DC.

Копирование из окна в картинку (bitmap).

0

8

Пётр написал(а):

Основное время выполняется BitBlt, а не StartDrawing и StopDrawing.

Ну, не скажите...

Код:
;capture a piece of screen
Procedure.l CaptureScreen(Left.l, Top.l, Width.l, Height.l)
  dm.DEVMODE
  BMPHandle.l
  srcDC = CreateDC_("DISPLAY", "", "", dm)
  trgDC = CreateCompatibleDC_(srcDC)
  BMPHandle = CreateCompatibleBitmap_(srcDC, Width, Height)
  SelectObject_( trgDC, BMPHandle)
  BitBlt_( trgDC, 0, 0, Width, Height, srcDC, Left, Top, #SRCCOPY)
  DeleteDC_( trgDC)
  ReleaseDC_( BMPHandle, srcDC)
  ProcedureReturn BMPHandle
EndProcedure
ExamineDesktops()
Width=DesktopWidth(0)
Height=DesktopHeight(0)
ScreenCaptureAddress = CaptureScreen(0, 0, Width, Height)
CreateImage(0, Width, Height)
StartDrawing(ImageOutput(0))
DrawImage(ScreenCaptureAddress, 0, 0)
StopDrawing()
ScreenCaptureAddress = CaptureScreen(0, 0, Width, Height)
CreateImage(1, Width, Height)
StartDrawing(ImageOutput(1))
DrawImage(ScreenCaptureAddress, 0, 0)
StopDrawing()
For y=0 To Height-1
  For x=0 To Width-1
    StartDrawing(ImageOutput(0))
    a=Point(x,y)
    StopDrawing()    
    StartDrawing(ImageOutput(1))
    b=Point(x,y)
    StopDrawing()
    If a<>b
      Debug "Скриншоты разные" 
      c=1
      End
    EndIf
  Next
Next
Debug "Скриншоты одинаковые" 

Тут время становится более чем заметным...
А ведь это сравнение всего лишь двух скриншотов...

Отредактировано Nigri_lupus (19.05.2023 19:37:48)

0

9

Nigri_lupus написал(а):

А ведь это сравнение всего лишь двух скриншотов...

Я категорически не в состоянии понять, зачем вам PB функции из библиотеки image для сравнения скриншотов.
Вы получаете средствами api адреса битмапов, разберитесь с их структурой в памяти и сравнивайте два куска памяти.
Как говорится вам сравнивать или рисовать?

Отредактировано useful (19.05.2023 20:12:19)

0

10

useful написал(а):

Я категорически не в состоянии понять, зачем вам PB функции из библиотеки image для сравнения скриншотов.
Вы получаете средствами api адреса битмапов, разберитесь с их структурой в памяти и сравнивайте два куска памяти.
Как говорится вам сравнивать или рисовать?

Мне сравнить, но КАК это сделать я не знаю.
Процедуру CaptureScreen, написанную на WinApi, я честно скомунизил из интернета.
Но взять чужой код и понять, как он работает - разные вещи. Всё, что я понял, CaptureScreen сохраняет картинку заданной области экрана где-то в памяти и возвращает системный ID этой картинки.
1. Где в памяти находится эта картинка?
2. Как создать копию этой памяти, чтобы не затереть её при следующих (втором, третьем и всех последующих) применениях этой функции(снимках экрана)?
3. И наконец как сравнить ?
Я не знаю.

0

11

Безнадёжно! Но если вдруг нет, то по смотрите как учатся другие: https://www.cyberforum.ru/win-api/thread912219.html
Если вы таки не собираетесь разбираться в том как изображения хранятся системой в памяти, то бросайте это гиблое дело.

p.s. Даже если не разбираться с тем как там в windows, я тоже не помню, лет 15 как не интересует ничего заточенного под одну операционную систему.
Я же давал ссылки на функции работы с буфером рисунка(холста) как с фрагментом в памяти, а не по пиксельно.

Код:
;capture a piece of screen
Procedure.l CaptureScreen(Left.l, Top.l, Width.l, Height.l)
  dm.DEVMODE
  BMPHandle.l
  srcDC = CreateDC_("DISPLAY", "", "", dm)
  trgDC = CreateCompatibleDC_(srcDC)
  BMPHandle = CreateCompatibleBitmap_(srcDC, Width, Height)
  SelectObject_( trgDC, BMPHandle)
  BitBlt_( trgDC, 0, 0, Width, Height, srcDC, Left, Top, #SRCCOPY)
  DeleteDC_( trgDC)
  ReleaseDC_( BMPHandle, srcDC)
  ProcedureReturn BMPHandle
EndProcedure
ExamineDesktops()
Width=DesktopWidth(0)
Height=DesktopHeight(0)
ScreenCaptureAddress = CaptureScreen(0, 0, Width, Height)
CreateImage(0, Width, Height)
StartDrawing(ImageOutput(0))
      Debug "Адрес памяти : " + Str(DrawingBuffer())
      Debug "Реальная длина одной линии  : " + Str(DrawingBufferPitch())    
      Debug "Пиксельный формат : " + Str(DrawingBufferPixelFormat())
DrawImage(ScreenCaptureAddress, 0, 0)
StopDrawing()
ScreenCaptureAddress = CaptureScreen(0, 0, Width, Height)
CreateImage(1, Width, Height)
StartDrawing(ImageOutput(1))
      Debug "Адрес памяти : " + Str(DrawingBuffer())
      Debug "Реальная длина одной линии  : " + Str(DrawingBufferPitch())    
      Debug "Пиксельный формат : " + Str(DrawingBufferPixelFormat())
DrawImage(ScreenCaptureAddress, 0, 0)
StopDrawing()
Debug #PB_PixelFormat_8Bits      ; 1 байт на пиксель, с палитрой
Debug #PB_PixelFormat_15Bits     ; 2 байта на пиксель 
Debug #PB_PixelFormat_16Bits     ; 2 байта на пиксель
Debug #PB_PixelFormat_24Bits_RGB ; 3 байта на пиксель (RRGGBB)
Debug #PB_PixelFormat_24Bits_BGR ; 3 байта на пиксель (BBGGRR)
Debug #PB_PixelFormat_32Bits_RGB ; 4 байта на пиксель (RRGGBB)
Debug #PB_PixelFormat_32Bits_BGR ; 4 байта на пиксель (BBGGRR)
Debug #PB_PixelFormat_ReversedY  ; Координата Y устройства вывода хранится в памяти в обращённом виде (нижний ряд хранится первым).
Debug #PB_PixelFormat_8Bits      | #PB_PixelFormat_ReversedY
Debug #PB_PixelFormat_15Bits     | #PB_PixelFormat_ReversedY
Debug #PB_PixelFormat_16Bits     | #PB_PixelFormat_ReversedY
Debug #PB_PixelFormat_24Bits_RGB | #PB_PixelFormat_ReversedY
Debug #PB_PixelFormat_24Bits_BGR | #PB_PixelFormat_ReversedY ;!!!!!!!! Наш формат
Debug #PB_PixelFormat_32Bits_RGB | #PB_PixelFormat_ReversedY
Debug #PB_PixelFormat_32Bits_BGR | #PB_PixelFormat_ReversedY

Отредактировано useful (20.05.2023 10:40:41)

0

12

Насколько я понял, функция CaptureScreen создает изображение и возвращает его дескриптор, т.е.  BMPHandle это дескриптор изображения. Я правильно понял?
Чтобы сравнить два куска памяти, скажем при помощи CompareMemory() нужен указатель на эти куски памяти. Собственно как и для того, чтобы когда скриншоты станут не нужны эту память очистить, потому как:

Код:
 ;capture a piece of screen
Procedure.l CaptureScreen(Left.l, Top.l, Width.l, Height.l)
  dm.DEVMODE
  BMPHandle.l
  srcDC = CreateDC_("DISPLAY", "", "", dm)
  trgDC = CreateCompatibleDC_(srcDC)
  BMPHandle = CreateCompatibleBitmap_(srcDC, Width, Height)
  SelectObject_( trgDC, BMPHandle)
  BitBlt_( trgDC, 0, 0, Width, Height, srcDC, Left, Top, #SRCCOPY)
  DeleteDC_( trgDC)
  ReleaseDC_( BMPHandle, srcDC)
  ProcedureReturn BMPHandle
EndProcedure
ExamineDesktops()
Width=DesktopWidth(0)
Height=DesktopHeight(0)
ScreenCaptureAddress = CaptureScreen(0, 0, Width, Height)
FreeMemory(ScreenCaptureAddress)

Работать явно не хочет.
Вопрос: Как зная дескриптор получить указатель?

0

13

Возможно какая нибудь структура типа BITMAPINFO содержит поля в которых есть размер и прочая инфа, и данные на пикселы.  Ещё момент, не обязательно DC экрана получать каждый раз когда нужен скриншот, скорее всего его можно получить один раз, а потом копировать с него данные, то есть он обновляется по мере обновления экрана. Опять же нужно ли тут копирование? Вы получили Bitmap с помощью структуры вытащили данные в другую область памяти, как бы кэш с которым сравнивать, то есть использовать CopyMemory(). Зачем промежуточные действия BitBlt()?

Использовать GetDIBits, в параметрах которого используется структура BITMAPINFO, когда функция вернёт указатель на структуру, то из неё можно прочитать данные пикселов. В описании сказано что lpvBits - Указатель на буфер, принимающий данные точечного рисунка, вот оно, выделить буфер например 16 Мб и передать его параметром и в него вернётся данные пикселов. Хотя со структурой наверно надёжнее, так как она автоматически выделит нужный размер памяти. Или вычислять размер по данным ширины и высоты.
Примеры GetDIBits нормально гуглятся.
https://www.purebasic.fr/english/viewto … 22#p521622
Подтверждение моих слов о GetDIBits https://www.purebasic.fr/english/viewto … 36#p517336
На оффоруме по GetDIBits куча результатов.
Попробовал в примере убрать BitBlt(), результат не был получен, но я пока не понимаю зачем создавать промежуточный DC.

Отредактировано AZJIO (22.05.2023 21:45:21)

0

14

Работа с изображениями формата DDB
Работа с изображениями формата DIB
Функция GetObject извлекает информацию для заданного графического объекта.

Отредактировано useful (23.05.2023 07:45:10)

0

15

useful, Вот, что пока-что мне удалось написать:

Код:
Procedure WaitCheckScreenChanges(x,y,Width,Height)
  FirstPair.a
  i.a
  Dim *mem(1)
  GDW=GetDesktopWindow_()
  DC_Scr=GetDC_(GDW)
  ImageNumber=CreateImage(#PB_Any, Width, Height)
  DC_Image=StartDrawing(ImageOutput(ImageNumber))
  Repeat
    If i=2
      FreeMemory(*Mem(1))
      FirstPair=1  
      i=1
    EndIf
    BitBlt_(DC_Image, 0, 0, Width, Height , DC_Scr, X, Y , #SRCCOPY)
    *mem(i)=EncodeImage(ImageNumber)
    i+1
  Until (FirstPair And CompareMemory(*Mem(0),*Mem(1) ,MemorySize(*Mem(0)))=0)
  StopDrawing()
  FreeMemory(*Mem(0))
  FreeMemory(*Mem(1))
  FreeImage(ImageNumber)
  ReleaseDC_(GDW,DC_Scr)
EndProcedure 
x=0
y=0
ExamineDesktops()
Width=DesktopWidth(0)
Height=DesktopHeight(0)
; Width=3000
; Height=3000
Time = ElapsedMilliseconds()
res=waitCheckScreenChanges(x,y,Width,Height)
Time = ElapsedMilliseconds()-Time
Debug time 

Это не совсем, то, что я хотел и знаю, что, вероятно можно и лучше...
Планировалось, чтобы работало немного по-другому, т.е.
SCE=ScreenEvent(x,y,Width,Height) ; Возвращает 1 если, в указанной области экрана, что-то поменялось, иначе 0....
А получилось, пока-что лишь:
WaitCheckScreenChanges(x,y,Width,Height)
Ждет, пока в  указанной области экрана что-то поменяется.

0

16

Привет, уважаемый Nigri_lupus!

Код:
           CreateImage(ImageNr,Width,Height)
           hDC  = StartDrawing(ImageOutput(ImageNr)) ;hDC    дескриптор целевого DC
           DeskDC = GetDC_(GetDesktopWindow_())  ;GetDC_(WindowID())       Get the output pointer  ;WIN32API  
  ;WIN32API  Функция BitBlt выполняет передачу битовых блоков данных о цвете, соответствующих прямоугольнику пикселей из  
  ;заданного исходного контекста устройства в целевой hDC контекст устройства.;Синтаксис:
  ;  HDC hdcDest, // дескриптор целевого DC                                 hDC  
  ;  int nXDest,  // x-коорд. левого верхнего угла целевого прямоугольника  0      (x координата куда ВЫВОЖУ на экран) 
  ;  int nYDest,  // y-коорд. левого верхнего угла целевого прямоугольника  0      (y координата куда ВЫВОЖУ на экран)   
  ;  int nWidth,  // ширина целевого прямоугольника                         Width   (ширина ХОТИМОГО скрина)    
  ;  int nHeight, // высота целевого прямоугольника                         Height  (высота ХОТИМОГО скрина)      
  ;  HDC hdcSrc,  // дескриптор исходного DC                                DeskDC             
  ;  int nXSrc,   // x-коорд. левого верхнего угла исходного прямоугольника (x координата старт точки СКРИНа Width*Height)                         
  ;  int nYSrc,   // y-коорд. левого верхнего угла исходного прямоугольника (y координата старт точки СКРИНа Width*Height)                        
  ;  DWORD dwRop  // код растровой операции                                 #SRCCOPY               
           BitBlt_(hDC,0,0,Width,Height,DeskDC,x,y,#SRCCOPY) ;WIN32API                  
           StopDrawing()           
           ReleaseDC_(GetDesktopWindow_(),DeskDC) ;Освобождает общий или оконный (не влияющий на класс или локальность)
            ;контекст устpойства, делая его доступным для дpугих пpикладных задач.
           SaveImage(ImageNr, "MY_SCREEN.jpeg", #PB_ImagePlugin_JPEG)
            
            
                                  *MemoryImage = EncodeImage(ImageNr, #PB_ImagePlugin_JPEG) ;
                                  ;Кодирует указанное изображение  и помещает его в созданный буфер памяти *MemoryImage^^^^

0

17

Скорость записи в ОЗУ зависит от стандарта  установленного ОЗУ в компе , его разрядности и частоты шины памяти.

Для стандарта  Ddr3  и частоте шины памяти 700 МГц при 64-битной шине памяти ОЗУ, пиковая скорость передачи данных составит примерно 11000 Мбайт/с  или  11 Мбайт/мс ,
Или  11 Кбайт/мкС.
Таким образом, если хотим просто записать в ОЗУ 110 Кбайт данных (рисунок для примера),
то это займет  10 мкС.
При 32-битной шине на это уйдет 20 мкС  , то есть в 2 раза больше времени.
То есть в реале, с учетом операционной системы компа, её разрядности, скорости Cpu проца и доповой скорости выполнения директив,
на запись( или чтение) в ОЗУ   100  Кбайт  данных  уйдёт примерно  50…100  мкС.

Итог, основное время в данном случае уходит не на обработку директив-команд,  а на
работу с ОЗУ.
Вот так можно примерно определить тайминг работы с ОЗУ – записи- чтения скриншота в зависимости от его размера.

0

18

Какой то код перевёл немного, может поможет чем? но здесь затык *pbmi\biSizeImage = ((*pbmi\biWidth * cClrBits +31) & ~31) /8 *pbmi\biHeight;

Код:
Structure tagRGBQUAD;цвет
  rgbBlue.b
  rgbGreen.b
  rgbRed.b
  rgbReserved.b
EndStructure



Structure tagBITMAPINFO;определяет измерения и сведения о цвете для DIB
  bmiHeader.BITMAPINFOHEADER 
  bmiColors.tagRGBQUAD[1]
EndStructure 
  
Procedure CreateBitmapInfoStruct(hBmp);типа создать структуру битмапа в памяти
 
   Protected bmp.BITMAP; 
   Protected pbmi.tagBITMAPINFO; 
   Protected cClrBits.w; 

    ;// Retrieve the bitmap's color format, width, and height. 
    If (Not GetObject_(hBmp, SizeOf(BITMAP),@bmp)) 

        MessageBox_(#Null, "GetObject error", "error", #MB_OK); 
	EndIf

    ;// Convert the color format To a count of bits. 
    cClrBits = (bmp\bmPlanes * bmp\bmBitsPixel); 
    If (cClrBits = 1) 
        cClrBits = 1; 
    ElseIf (cClrBits <= 4) 
        cClrBits = 4; 
    ElseIf (cClrBits <= 8) 
        cClrBits = 8; 
    ElseIf (cClrBits <= 16) 
        cClrBits = 16; 
    ElseIf (cClrBits <= 24) 
        cClrBits = 24; 
      Else 
        cClrBits = 32; 
    EndIf
    ;// Allocate memory For the BITMAPINFO Structure. (This Structure 
    ;// contains a BITMAPINFOHEADER Structure And an Array of RGBQUAD 
    ;// Data structures.) 

     If (cClrBits <> 24) 
         *pbmi.BITMAPINFOHEADER =  LocalAlloc_(LPTR, SizeOf(BITMAPINFOHEADER) + SizeOf(RGBQUAD) * (1<< cClrBits)); 

     ;// There is no RGBQUAD Array For the 24-bit-per-pixel format. 

     Else 
         *pbmi.BITMAPINFOHEADER = LocalAlloc_(LPTR, SizeOf(BITMAPINFOHEADER)); 

      ;// Initialize the fields in the BITMAPINFO Structure. 

      *pbmi\biSize= SizeOf(BITMAPINFOHEADER); 
      *pbmi\biWidth = bmp\bmWidth; 
      *pbmi\biHeight = bmp\bmHeight; 
      *pbmi\biPlanes = bmp\bmPlanes; 
      *pbmi\biBitCount = bmp\bmBitsPixel; 
     EndIf
  
  
    If (cClrBits < 24) 
        *pbmi\biClrUsed = (1<<cClrBits); 

    ;// If the bitmap is Not compressed, set the BI_RGB flag. 
    *pbmi\biCompression = #BI_RGB; 

    ;// Compute the number of bytes in the Array of color 
    ;// indices And store the result in biSizeImage. 
    ;// For Windows NT/2000, the width must be DWORD aligned unless 
    ;// the bitmap is RLE compressed. This example shows this. 
    ;// For Windows 95/98, the width must be WORD aligned unless the 
    ;// bitmap is RLE compressed.
    *pbmi\biSizeImage = ((*pbmi\biWidth * cClrBits +31) & ~31) /8 *pbmi\biHeight; 
    ;// Set biClrImportant To 0, indicating that all of the 
    ;// device colors are important. 
    *pbmi\biClrImportant = 0;
    EndIf
     Return pbmi;
EndProcedure

Procedure doSaveScreen(hdc,*rect.RECT,*fileName)

	Protected hdcMem;
	Protected hMyBitmap;
	Protected pBitmapInfo;
	Protected point.Point;

	hdcMem=CreateCompatibleDC_(hdc);
	hMyBitmap=CreateCompatibleBitmap_(hdc, *rect\right-*rect\left, *rect\bottom-*rect\top);
	

	SelectObject_(hdcMem, hMyBitmap);
	
	
	BitBlt_(hdcMem, 0, 0, *rect\right-*rect\left, *rect\bottom-*rect\top, hdc, *rect\left, *rect\top, #SRCCOPY);

	pBitmapInfo=CreateBitmapInfoStruct_(hMyBitmap);
	CreateBMPFile_(fileName, pBitmapInfo, hMyBitmap, hdcMem);

	DeleteDC_(hdcMem);
	DeleteObject_(hMyBitmap);
	LocalFree_(pBitmapInfo);

EndProcedure

Procedure SaveScreen(hwnd)
  Protected hdc
  Protected rect.rect
  hdc=CreateDC_("DISPLAY", #Null, #Null, #Null)
  rect\left=0
  rect\top=0
	rect\right=GetDeviceCaps_(hdc, #HORZRES);
	rect\bottom=GetDeviceCaps_(hdc, #VERTRES)
  doSaveScreen_(hdc, rect, "fullScreen.bmp");
	DeleteDC_(hdc);
  
EndProcedure

0

19

Задача :
получить содкржимое отдельного окна в котором проигрывается видео (на паузе) и записать в "файл.вмр" на диск.
Пользоваться библиотекой AVIfile32.dll неудобно, так как там нужно знать номер кадра.
Вероятно это возможно через BitBlt
К сожалению (мне) не удаётся правильно считать содержимое окна с видео-кадром = получаю чёрный квадрат.

Кто-нибудь знает Правильный ответ ???

0

20

Думаю надо получить хендл окна где видео далее контекст dc и оттуда скринить или типа координаты по хендлу а контекст экрана и типа скринить по координатам окна где видео но от контекста экрана?

0


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Как поместить снимок экрана в память?