[bmx] Screen Capture Mod by TomToad [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:41

Previous topic - Next topic

BlitzBot

Title : Screen Capture Mod
Author : TomToad
Posted : 1+ years ago

Description : Put this code into (BlitzMAX)mod   oad.modcapture.mod directory and build the module.
Usage:
Function ScreenCapture:TPixMap()

Will capture the screen and return it in a pixmap.  If you call this function before calling Graphics, you'll capture the desktop image.

Function GetScreenCapturWidth:int()

will return the width of the captured image

Function GetScreenCaptureHeight:int()

Will get the Height of the captured image

Edit:  Don't need all the lines I commented out :)


Code :
Code (blitzmax) Select
Module toad.capture

Import BRL.Pixmap
Import pub.Win32
Import BRL.Basic

Extern "Win32"
Function GetPixel:Int(hdc:Int,x:Int,y:Int)
End Extern

Private
Global Width:Int
Global Height:Int

Public
Function ScreenCapture:TPixmap()
Local Pixmap:TPixmap
Local Pixel:Int
Local hdc:Int = GetDC(Null)

Width:Int = GetDeviceCaps(hdc,HORZRES)
Height:Int = getdevicecaps(hdc,VERTRES)
Pixmap = CreatePixmap(Width,Height,PF_RGBA8888)
For Local y = 0 To Height - 1
For Local x = 0 To Width - 1
Pixel = GetPixel(hdc,x,y)
WritePixel(PixMap,x,y,$FF000000+(Pixel & $ff)Shl 16+(Pixel & $ff00)+(Pixel & $ff0000)Shr 16)
Next
Next

Return PixMap

End Function

Function GetScreenCaptureWidth:Int()
Return Width
End Function

Function GetScreenCaptureHeight:Int()
Return Height
End Function


Comments :


Boiled Sweets(Posted 1+ years ago)

 I use this to draw the desktop in the loop
DrawPixmap( desktopPixMap, 0, 0 )
This causes the screen saver to run rather jerkily, is there a better way?


TomToad(Posted 1+ years ago)

 Try loading the pixmap into a TImageLocal DeskTopImage:TImage = LoadImage(desktopPixMap)You can capture and load all in one line with Local DesktopImage:TImage = LoadImage(ScreenCapture())That's the way I did it in my SpinIt screensaver.  One problem though is that some older cards can't handle a TImage as big as the desktop so you might be better off loading as an animation.Local DeskTopImage:TImage = LoadAnimImage(ScreenCapture(),TileWidth,TileHeight,0,CellWidth*CellHeight)Where TileWidth and TileHeight are the width and height of the tiles in pixels, and CellWidth and CellHeight are the number of tiles in the X and Y directions.


Who was John Galt?(Posted 1+ years ago)

 Cheers Tom this one was useful for me.


fredborg(Posted 1+ years ago)

 Hi,GetPixel is terribly slow when Aero is enabled in Vista. It's much faster to copy the screen to a different bitmap and then read from that.This is one way of doing that:Import pub.win32

SuperStrict

Extern "win32"
Function ReleaseDC:Int(hwnd:Int,hdc:Int)
Function GetPixel:Int(hdc:Int,x:Int,y:Int)
End Extern

Const SRCCOPY:Int = $CC0020

Function GrabScreen:TPixmap(x:Int=0,y:Int=0,width:Int=0,height:Int=0)

Local hdc:Int = GetDC(Null)

If width  <= 0 Then width  = 100000000000
If height <= 0 Then height = 100000000000

Local maxWidth:Int = GetDeviceCaps(hdc,HORZRES)-x
Local maxHeight:Int = GetDeviceCaps(hdc,VERTRES)-y

width = Min(maxWidth,width)
height = Min(maxHeight,height)

Local newHdc:Int = CreateCompatibleDC(hdc)
If newHdc = 0 Then Return Null

Local newBmp:Int = CreateCompatibleBitmap(hdc,width,height)
If newBmp = 0
ReleaseDC(Null,newHdc)
Return Null
EndIf

If SelectObject(newHdc, newBmp) = False
Return Null
EndIf

If BitBlt(newHdc,0,0,width,height,hdc,x,y,SRCCOPY) = False
Return Null
EndIf

Local pixmap:TPixmap = CreatePixmap(width,height,PF_RGBA8888)

For Local y:Int = 0 Until height
For Local x:Int = 0 Until width
Local pixel:Int = GetPixel(newHdc,x,y)
WritePixel(pixmap,x,y,$FF000000+(pixel & $ff) Shl 16 + (pixel & $ff00) + (pixel & $ff0000) Shr 16)
Next
Next

DeleteObject(newBmp)
ReleaseDC(Null,newHdc)

Return pixmap

End Function