Hi,

I tried the following code to capture the contents of the foreground window to an avi-file. It works under Python 2.6 and OpenCV2.0 though it only takes about 210 shots and then crashes. I think it might be a memory problem. Any ideas? You need to resize the window to 640x480 for it to work. Error message is:

Traceback (most recent call last):
File "D:/Python26/Programme/WindowsAPI/capture_foreground1.py", line 66, in <module>
[iplimage, t] = capture_window(hwnd)
File "D:/Python26/Programme/WindowsAPI/capture_foreground1.py", line 32, in capture_window
saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)
win32ui.error: CreateCompatibleDC failed
Output #0, avi, to 'captured.avi':
Stream #0.0: Video: mpeg4, yuv420p, 680x480, q=2-31, 20889 kb/s, 90k tbn, 8 tbc

from opencv import adaptors
from opencv import cv
from opencv import highgui
import win32gui, win32ui, win32con, win32api
import PIL.Image, PIL.ImageGrab, time


def capture_window(hwnd):
    global iplimage
    try:
        del iplimage
    except:
        pass
    if not hwnd:
        raise 'Window not found'
    t0=time.clock()
    # compute height h and width w
    l,t,r,b=win32gui.GetWindowRect(hwnd)
    h=b-t
    w=r-l
    # get DrawCanvas of the window
    hwndDC = win32gui.GetWindowDC(hwnd)
    # create the DC from handle
    mfcDC=win32ui.CreateDCFromHandle(hwndDC)
    # create compatible DC from it
    saveDC=mfcDC.CreateCompatibleDC()
    # create PyCBitmap
    saveBitMap = win32ui.CreateBitmap()
    # create compatible bitmap with width w and height h
    saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)
    saveDC.SelectObject(saveBitMap)
    # screencopy the contents
    saveDC.BitBlt((0,0),(w, h) , mfcDC, (0,0), win32con.SRCCOPY)
    # get the bitmap info
    bmpinfo = saveBitMap.GetInfo()
    # get the string of image data
    bmpstr = saveBitMap.GetBitmapBits(True)
    # win32gui.ReleaseDC(hwnd, mfcDC)
    # win32gui.ReleaseDC(hwnd, saveDC)
    del mfcDC
    del saveDC
    del saveBitMap
    # convert it to PIL image
    im = PIL.Image.frombuffer('RGB', (bmpinfo['bmWidth'], bmpinfo['bmHeight']), bmpstr, 'raw', 'BGRX', 0, 1)
    # convert it to IPL image
    iplimage = adaptors.PIL2Ipl(im)
    del im
    t = time.clock()
    return [iplimage, float(t-t0)]

if __name__ == '__main__':
    MPEG4 = 0x58564944
    fps = 8
    hwnd = win32gui.GetForegroundWindow()
    l,t,r,b = win32gui.GetWindowRect(hwnd)
    [iplimage, t] = capture_window(hwnd)
    frame_size = cv.cvGetSize (iplimage)
    writer = highgui.cvCreateVideoWriter ("captured.avi", MPEG4,
                                          fps, frame_size, True)
    i = 0
    while 1:
        print i,
        i = i + 1
        [iplimage, t] = capture_window(hwnd)
        highgui.cvWriteFrame (writer, iplimage)
        k = highgui.cvWaitKey (1)
        print k
        if k == '\x1b':
            break
        
    highgui.cvReleaseVideoWriter (writer)

I found a workaround. There are two modules existing which might help. These are called vnc2flv and pyvnc2swf which can be found here:

You need to setup a VNC server running and these neat little python programs capture video input from your local desktop. No sound though. But can added with the vnc2flv to a flash movie file with flvaddmp3.py afterwards.

http://www.unixuser.org/~euske/python/vnc2flv/index.html
http://www.unixuser.org/~euske/vnc2swf/
Andreas

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.