2011-01-03 2 views
0

Я искал альтернативные решения для захвата экрана в растровое изображение на машине Windows.Захват экрана в окнах с использованием ctypes

Теперь я знаю, что PIL имеет библиотеку ImageGrab, и я, вероятно, в конечном итоге ее использую. Однако во время моих поисков я столкнулся с решением, которое использует ctypes для доступа к функциям gdi32.dll и использует их для захвата экрана. Было одно конкретное решение, с которым я столкнулся, который не работает, и я пытался выяснить, что не так.

Вот исходный код:

from ctypes import * 

class Bitmap(Structure): 
    _fields_ = [("bitmapType", c_long), 
       ("width", c_long), 
       ("height", c_long), 
       ("widthBytes", c_long), 
       ("planes", c_short), 
       ("bitsPerPixel", c_short), 
       ("data", POINTER(c_ulong))] 

if __name__ == "__main__": 
    user32 = WinDLL("user32.dll") 
    gdi32 = WinDLL("gdi32.dll") 

    #Constants 
    SM_CXSCREEN = 0 
    SM_CYSCREEN = 1 
    SRCCOPY = 0xCC0020 

    #Capture the Bitmap 
    width = user32.GetSystemMetrics(SM_CXSCREEN) 
    height = user32.GetSystemMetrics(SM_CYSCREEN) 
    screenDC = user32.GetWindowDC(user32.GetDesktopWindow()) 
    captureDC = gdi32.CreateCompatibleDC(screenDC) 
    captureBitmap = gdi32.CreateCompatibleBitmap(screenDC, width, height) 
    gdi32.SelectObject(captureDC, captureBitmap) 
    gdi32.BitBlt(captureDC, 0, 0, width, height, screenDC, 0, 0, SRCCOPY) 

    picture = Bitmap() 
    gdi32.GetObjectA(captureBitmap, 24, byref(picture)) 

Теперь, мне кажется, что в конце программы, автор пытается скопировать растровое изображение объекта Bitmap, но: 1. Я не удалось чтобы найти документацию функции gdi32.GetObjectA 2. При попытке просмотреть данные внутри файла picutre.data (надеюсь, что я был не прав, обратившись к picture.data.contents), я получаю ошибку Value: «NULL-указатель доступа».

Теперь, на той странице, где я нашел этот фрагмент кода, был ответ на проблему, но он был немного расплывчатым и не очень информативным. Ответ гласил:

 
You must allocate the integer array for the data pointer of the BITMAP structure. 
GetObject doesn't it for you. 

не Если функция gdi32.CreateCompatibleBitmap уже выделить эту память, и не не GetObject просто скопировать указатель на представление Python структуры растрового?

Я действительно запутался здесь, любой легкий пролив на эту проблему был бы действительно оценен. (у меня уже есть, как 15 открытых вкладок с MSDN gdi32 ссылок и более 15 с ctypes ссылок, но, видя, как я не имеют твердое понимание на любой, я чувствую, что я иду по кругу)

ответ

0

GetObject не возвращает целое растровое изображение. picture.data на самом деле NULL после вызова GetObject. Для чтения растрового изображения вам понадобится GetDIBits. Вот соответствующий отрывок из документов GetObject.

If hgdiobj is a handle to a bitmap created by calling CreateDIBSection, and the specified buffer is large enough, the GetObject function returns a DIBSECTION structure. In addition, the bmBits member of the BITMAP structure contained within the DIBSECTION will contain a pointer to the bitmap's bit values.

If hgdiobj is a handle to a bitmap created by any other means, GetObject returns only the width, height, and color format information of the bitmap. You can obtain the bitmap's bit values by calling the GetDIBits or GetBitmapBits function.

Смежные вопросы