Copying a window into a bitmap...

Everything else that doesn't fall into one of the other PB categories.
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Hi-Toro.

OK, I can basically copy a window's image into another window (see code below), but can anyone tell how you get the image into a (Windows) bitmap? I've tried lots of variations on CreateCompatibleDC/Bitmap and SelectObject, but nothing works :(

Code: Select all

; NOTE: Currently the CopyWindow is fixed to use the dimensions of the desktop...

Procedure.w ScreenWidth ()
  ProcedureReturn GetSystemMetrics_ (#SM_CXSCREEN)
EndProcedure

Procedure.w ScreenHeight ()
  ProcedureReturn GetSystemMetrics_ (#SM_CYSCREEN)
EndProcedure

Procedure CopyWindow (fromWindow, toWindow, x, y)

  width = ScreenWidth ()
  height = ScreenHeight ()
  
  fromDC = GetWindowDC_ (fromWindow)
      toDC = GetDC_ (toWindow)
          BitBlt_ (toDC, 0, 0, width, height, fromDC, x, y, #SRCCOPY)
      ReleaseDC_ (toWindow, toDC)
  ReleaseDC_ (fromWindow, fromDC)

EndProcedure

OpenWindow (0, 320, 200, 320, 200, #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget, "Test")

Repeat
    CopyWindow (GetDesktopWindow_ (), WindowID (), WindowMouseX (), WindowMouseY ())
Until WaitWindowEvent () = #PB_EventCloseWindow

End

--
See ya,
James L Boyd.
http://www.hi-toro.com/
--
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by tinman.
Originally posted by Hi-Toro

StartDrawing() returns a pointer to the DC of whatever you are drawing to so you should be able to use StartDrawing(ImageOutpout()) to be able to copy to an image. Is that bitmappy enough for you?
--
It's not minimalist - I'm increasing efficiency by reducing input effort.
(Win98first ed. + SP1, PB3.40)
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Hi-Toro.

You genius -- here's the fixed version :)

Code: Select all

; NOTE: Currently the CopyWindow is fixed to use the dimensions of the desktop...

Procedure.w ScreenWidth ()
  ProcedureReturn GetSystemMetrics_ (#SM_CXSCREEN)
EndProcedure

Procedure.w ScreenHeight ()
  ProcedureReturn GetSystemMetrics_ (#SM_CYSCREEN)
EndProcedure

Procedure CopyWindow (fromWindow, x, y)

  width = ScreenWidth ()
  height = ScreenHeight ()
  
  fromDC = GetWindowDC_ (fromWindow)
      toDC = StartDrawing (ImageOutput ())
          BitBlt_ (toDC, 0, 0, width, height, fromDC, x, y, #SRCCOPY)
      StopDrawing ()
  ReleaseDC_ (fromWindow, fromDC)

EndProcedure

OpenWindow (0, 320, 200, 320, 200, #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget, "Test")

CreateImage (0, ScreenWidth (), ScreenHeight ())

Repeat
    CopyWindow (GetDesktopWindow_ (), WindowMouseX (), WindowMouseY ())
    StartDrawing (WindowOutput ())
    DrawImage (ImageID (), 0, 0)
    StopDrawing ()
Until WaitWindowEvent () = #PB_EventCloseWindow

End
Thanks yet again Tinman!


--
See ya,
James L Boyd.
http://www.hi-toro.com/
--
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by MrVainSCL.

Hello Hi-Toro
I tested and compared your first and new version.... The new version where you use the BasicCommands Start/StopDrawing() is veeerrryyy slow here on my computer due fact Start/StopDrawing is not really fast and you call it every loop...

Your first version works verrryy smooth here!

PIII450, 256MB Ram, 80GB HD + 6,4 GB, RivaTNT, DirectX8.1, SB AWE64, Win2000 + all Updates...

greetz
MrVainSCL! aka Thorsten
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by fred.
Originally posted by MrVainSCL
I tested and compared your first and new version.... The new version where you use the BasicCommands Start/StopDrawing() is veeerrryyy slow here on my computer due fact Start/StopDrawing is not really fast and you call it every loop...
StartDrawing() isn't slow at all, but in the second version, the bitmap is copied in a temporary image before being displayed. In the first version, it was copied directly to the window. So I suggest to use WindowOuput() instead of ImageOutput() and it should be exactly the same speed, and should works ok.
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Franco.

James, your code is really slow.
Look at this old code, maybe it helps.
viewtopic.php?t=1482


Have a nice day...

Franco
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Hi-Toro.

Actually, I was just trying to get the image itself in the first place -- displaying it in a window was mainly for test purposes! Thanks anyway, all!


--
See ya,
James L Boyd.
http://www.hi-toro.com/
--
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by dmoc.

Here's my hacked version of a procedure out of Danilo's PureGL example. Note I'm not actually loading a bitmap. This proc grabs the desktop instead.

Procedure.l LoadBMP(Filename$)
Structure ReturnSize
Width.l
Height.l
EndStructure
Shared giveBack.ReturnSize

DC.l = GetDC_(0)
MDC.l = CreateCompatibleDC_(DC)

Image.l = CreateCompatibleBitmap_(DC,GetSystemMetrics_(#SM_CXSCREEN),GetSystemMetrics_(#SM_CYSCREEN))

SelectObject_(MDC,Image)
BitBlt_(MDC, 0, 0, GetSystemMetrics_(#SM_CXSCREEN), GetSystemMetrics_(#SM_CYSCREEN),DC, 0, 0, $0CC0020)

hBitmap = GetCurrentObject_(MDC, 7)

bm.BITMAP
bm = GetObject_(hBitmap , SizeOf( BITMAP ), @bm )

; Determine how big the image is
x = bm\bmBitsPixel / 8
iPixelSize = x

; Resize array To fit image Data size
lImageSize = bm\bmWidth * bm\bmHeight * iPixelSize

Dim baImageData(lImageSize/2)

; Read in the image Data

cClrBits.w = bm\bmPlanes * bm\bmBitsPixel

bmih.BITMAPINFOHEADER

bmih\biSize = SizeOf(BITMAPINFOHEADER)
bmih\biWidth = bm\bmWidth
bmih\biHeight = bm\bmHeight
bmih\biPlanes = bm\bmPlanes

; My desktop is 32 bit but I only wanted 24. GetDIBits converts the src if it does
; not match the spec in the BITMAPINFOHEADER

; bmih\biBitCount = bm\bmBitsPixel
bmih\biBitCount = 24
bmih\biClrUsed = 0
bmih\biCompression = #BI_RGB;
bmih\biSizeImage = ((bm\bmWidth + 7) /8 ) * bm\bmHeight * cClrBits
bmih\biClrImportant = 0

bmi.BITMAPINFO
bmi\bmiHeader = bmih

GetDIBits_(DC, Image, 0, bm\bmHeight, @baImageData(0), @bmih, #DIB_RGB_COLORS)

giveBack\Width = bm\bmWidth
giveBack\Height = bm\bmHeight

DeleteObject_(Image)
DeleteDC_(MDC)
ReleaseDC_(0,DC)

ProcedureReturn @giveBack
EndProcedure
Post Reply