Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как "сфотографировать" экран Windows?

2.9K
11 августа 2005 года
pushkin
43 / / 13.09.2004
Как "сфотографировать" экран Windows и записать его в Bitmap-файл, например?
243
12 августа 2005 года
pacific_7
1.9K / / 06.09.2004
Цитата:
Originally posted by pushkin
Как "сфотографировать" экран Windows и записать его в Bitmap-файл, например?


Сымитировать событие клавиатуры - нажатие клавиши PrtSc? Далее - работа с функциями Clipboard. Об этом на rsdn.ru рассказано. Что-то мне кажется в том же разделе и про фотографию экрана было написано, хотя могу и ошибаться.

2.4K
12 августа 2005 года
Lenin
51 / / 05.12.2004
Цитата:
Originally posted by pacific_7
Сымитировать событие клавиатуры - нажатие клавиши PrtSc? Далее - работа с функциями Clipboard. Об этом на rsdn.ru рассказано. Что-то мне кажется в том же разделе и про фотографию экрана было написано, хотя могу и ошибаться.


Можно bitblt заюзать

406
13 августа 2005 года
vitaly2003s
481 / / 27.07.2004
Весь алгоритм копирования экрана в bmp файл можно сделать следующим образом:
Код:
HANDLE DDBToDIB( HBITMAP bitmap, DWORD dwCompression )
{
    BITMAP          bm;
    BITMAPINFOHEADER    bi;
    LPBITMAPINFOHEADER  lpbi;
    DWORD           dwLen;
    HANDLE          hDIB;
    HANDLE          handle;
    HDC             hDC;
    HPALETTE        hPal;

    // The function has no arg for bitfields
    if( dwCompression == BI_BITFIELDS )
        return NULL;

        hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);

    ZeroMemory(&bm,sizeof(bm));
    // Get bitmap information
    GetObject(bitmap,sizeof(bm),(LPSTR)&bm);

    // Initialize the bitmapinfoheader
    bi.biSize       = sizeof(BITMAPINFOHEADER);
    bi.biWidth      = bm.bmWidth;
    bi.biHeight         = bm.bmHeight;
    bi.biPlanes         = 1;
    bi.biBitCount       = bm.bmPlanes * bm.bmBitsPixel;
    bi.biCompression    = dwCompression;
    bi.biSizeImage      = 0;
    bi.biXPelsPerMeter  = 0;
    bi.biYPelsPerMeter  = 0;
    bi.biClrUsed        = 0;
    bi.biClrImportant   = 0;

    // Compute the size of the  infoheader and the color table
    int nColors = (1 << bi.biBitCount);
    if( nColors > 256 )
        nColors = 0;
    dwLen  = bi.biSize + nColors * sizeof(RGBQUAD);

    // We need a device context to get the DIB from
    hDC = GetDC(NULL);
    hPal = SelectPalette(hDC,hPal,FALSE);
    RealizePalette(hDC);

    // Allocate enough memory to hold bitmapinfoheader and color table
    hDIB = GlobalAlloc(GMEM_FIXED,dwLen);

    if (!hDIB){
        SelectPalette(hDC,hPal,FALSE);
        ReleaseDC(NULL,hDC);
        return NULL;
    }

    lpbi = (LPBITMAPINFOHEADER)hDIB;

    *lpbi = bi;

    // Call GetDIBits with a NULL lpBits param, so the device driver
    // will calculate the biSizeImage field
    GetDIBits(hDC, bitmap, 0L, (DWORD)bi.biHeight,
            (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);

    bi = *lpbi;

    // If the driver did not fill in the biSizeImage field, then compute it
    // Each scan line of the image is aligned on a DWORD (32bit) boundary
    if (bi.biSizeImage == 0){
        bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
                        * bi.biHeight;

        // If a compression scheme is used the result may infact be larger
        // Increase the size to account for this.
        if (dwCompression != BI_RGB)
            bi.biSizeImage = (bi.biSizeImage * 3) / 2;
    }

    // Realloc the buffer so that it can hold all the bits
    dwLen += bi.biSizeImage;
    if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))
        hDIB = handle;
    else{
        GlobalFree(hDIB);

        // Reselect the original palette
        SelectPalette(hDC,hPal,FALSE);
        ReleaseDC(NULL,hDC);
        return NULL;
    }

    // Get the bitmap bits
    lpbi = (LPBITMAPINFOHEADER)hDIB;

    // FINALLY get the DIB
    BOOL bGotBits = GetDIBits( hDC, bitmap,
                0L,             // Start scan line
                (DWORD)bi.biHeight,     // # of scan lines
                (LPBYTE)lpbi            // address for bitmap bits
                + (bi.biSize + nColors * sizeof(RGBQUAD)),
                (LPBITMAPINFO)lpbi,     // address of bitmapinfo
                (DWORD)DIB_RGB_COLORS);     // Use RGB for color table

    if( !bGotBits )
    {
        GlobalFree(hDIB);
       
        SelectPalette(hDC,hPal,FALSE);
        ReleaseDC(NULL,hDC);
   
        return NULL;
    }
   
    SelectPalette(hDC,hPal,FALSE);
    ReleaseDC(NULL,hDC);

    return hDIB;
}

int WriteDIB( LPTSTR szFile, HANDLE hDIB)
{
    BITMAPFILEHEADER    hdr;
    LPBITMAPINFOHEADER  lpbi;

    if (!hDIB)
        return FALSE;

    HANDLE hf1;
    DWORD  lp;

 hf1= CreateFile(szFile,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
                if(hf1==INVALID_HANDLE_VALUE && GetLastError()==ERROR_FILE_EXISTS )
                {
                    return -2;
                }
                else if(hf1==INVALID_HANDLE_VALUE)
                {
                MessageBox(NULL,"Impossible to create new file","Warning",MB_OK);
                return -1;
                }
   
    lpbi = (LPBITMAPINFOHEADER)hDIB;

    int nColors = 1 << lpbi->biBitCount;

    // Fill in the fields of the file header
    hdr.bfType      = ((WORD) ('M' << 8) | 'B');    // is always "BM"
    hdr.bfSize      = GlobalSize (hDIB) + sizeof( hdr );
    hdr.bfReserved1     = 0;
    hdr.bfReserved2     = 0;
    hdr.bfOffBits       = (DWORD) (sizeof( hdr ) + lpbi->biSize +
                        nColors * sizeof(RGBQUAD));

    // Write the file header
    WriteFile(hf1,&hdr,sizeof(hdr),&lp,NULL);

    // Write the DIB header and the bits
    WriteFile(hf1,lpbi,GlobalSize(hDIB),&lp,NULL);

    CloseHandle( hf1);
    return 0;
}

bool ScreenToFile(char* path)
  {
   HDC hdc=GetDC(GetDesktopWindow());
   HDC hd=CreateCompatibleDC(hdc);
   int cx=GetSystemMetrics(SM_CXSCREEN);
   int cy=GetSystemMetrics(SM_CYSCREEN);
   HBITMAP hbm =CreateCompatibleBitmap(hdc,cx,cy);
   HBITMAP holdbmp=(HBITMAP)SelectObject(hd,hbm);
   BitBlt(hd,0,0,cx,cy,hdc,0,0,SRCCOPY);
   HANDLE hff =DDBToDIB(hbm,BI_RGB);
   bool b=false;
   if(hff)
     {
     WriteDIB(path,hff);
     GlobalFree(hff);
     b=true;
     }
   DeleteObject(SelectObject(hd,holdbmp));
   DeleteDC(hd);
   ReleaseDC(GetDesktopWindow(),hdc);
  return b;
  }

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
//save current screen to bmp file
ScreenToFile("c:\\screen.bmp");
return 0;
}
2.9K
17 августа 2005 года
pushkin
43 / / 13.09.2004
Всем большое спасибо - все уже работает (делаю троян) :)))
2.9K
25 августа 2005 года
pushkin
43 / / 13.09.2004
И еще тут по ходу работы у меня возникло пару вопросов.

Оказывается, что функция GetDIBits очень медленная. Я проводил замеры: сначала я делал 100 скринов под ряд, и сразу записывал их на диск - на это уходило 21 секунда, затем я просто запустил эту функцию 100 раз под ряд и на диск ничего не писал - получилось 19 секунд. Т. е., эта функция - самое узкое место в алгоритме, даже конвертирование файла в JPEG практически не отражается на общей производительности. Есть ли какой-нибудь другой, более быстрый способ делать скриншоты?

И еще вопрос по поводу конвертирования в Jpeg. Для этого я пользовался библиотекой Intel JPEG Library (ijl15.dll). Так вот, программа требует наличия этой DLL в системе и не запускается вообще, если ее не находит. Есть ли способ как-то влинковать функции из DLL статически прямо в программу?
Или есть ли какие-нибудь другие библиотеки, распространяемые с исходниками?
299
25 августа 2005 года
3D Bob
885 / / 18.04.2005
Цитата:
Originally posted by pushkin
И еще тут по ходу работы у меня возникло пару вопросов.

Оказывается, что функция GetDIBits очень медленная. Я проводил замеры: сначала я делал 100 скринов под ряд, и сразу записывал их на диск - на это уходило 21 секунда, затем я просто запустил эту функцию 100 раз под ряд и на диск ничего не писал - получилось 19 секунд. Т. е., эта функция - самое узкое место в алгоритме, даже конвертирование файла в JPEG практически не отражается на общей производительности. Есть ли какой-нибудь другой, более быстрый способ делать скриншоты?

И еще вопрос по поводу конвертирования в Jpeg. Для этого я пользовался библиотекой Intel JPEG Library (ijl15.dll). Так вот, программа требует наличия этой DLL в системе и не запускается вообще, если ее не находит. Есть ли способ как-то влинковать функции из DLL статически прямо в программу?
Или есть ли какие-нибудь другие библиотеки, распространяемые с исходниками?



Я уверен, что в стандартной библиотеке мастдая должна быть. Так что ожно использовать встроеную библиотеку на компьютере пользователя. Например этой библиотекой кажется должен обладать хотя бы Paint.

2.4K
25 августа 2005 года
Lenin
51 / / 05.12.2004
Цитата:
Originally posted by pushkin
И еще тут по ходу работы у меня возникло пару вопросов.

Оказывается, что функция GetDIBits очень медленная. Я проводил замеры: сначала я делал 100 скринов под ряд, и сразу записывал их на диск - на это уходило 21 секунда, затем я просто запустил эту функцию 100 раз под ряд и на диск ничего не писал - получилось 19 секунд. Т. е., эта функция - самое узкое место в алгоритме, даже конвертирование файла в JPEG практически не отражается на общей производительности. Есть ли какой-нибудь другой, более быстрый способ делать скриншоты?

И еще вопрос по поводу конвертирования в Jpeg. Для этого я пользовался библиотекой Intel JPEG Library (ijl15.dll). Так вот, программа требует наличия этой DLL в системе и не запускается вообще, если ее не находит. Есть ли способ как-то влинковать функции из DLL статически прямо в программу?
Или есть ли какие-нибудь другие библиотеки, распространяемые с исходниками?


BitBlt(DestinationDeviceContext,0,0,ScreenResWidth,ScreenHeight,GetDC(GetDesctopWindow()),0,0,SRCCOPY);
И картинка в DestinationDeviceContext'е.

2.9K
29 августа 2005 года
pushkin
43 / / 13.09.2004
Цитата:
Originally posted by Lenin
BitBlt(DestinationDeviceContext,0,0,ScreenResWidth,ScreenHeight,GetDC(GetDesctopWindow()),0,0,SRCCOPY);
И картинка в DestinationDeviceContext'е.


Толку мне от картинки в другом контексте - мне надо получить сами биты, а для этого и используется функция GetDIBits. Я и так пользовался функцией BitBlt для копирования кортинки из контекста в контекст.

P. S. сначала читай, что написано выше.

406
29 августа 2005 года
vitaly2003s
481 / / 27.07.2004
Цитата:
Originally posted by pushkin
Толку мне от картинки в другом контексте - мне надо получить сами биты, а для этого и используется функция GetDIBits. Я и так пользовался функцией BitBlt для копирования кортинки из контекста в контекст.

P. S. сначала читай, что написано выше.


Думаю можно сделать быстрей,и вместо каждого раза получения массива битов с GetDIBits картинки можно создать один раз этот масссив с помощью CreateDIBSection и затем при последующих вызовах уже использовать его и все это реализовать в классе. Попробуй сам сделать,не получится помогу.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог