在C - windows中截图

inn6fuwd  于 2021-05-29  发布在  Windows
关注(0)|答案(2)|浏览(160)

我想在我的windows机器上用C截图,然后保存为jpg或bmp或其他格式。无论如何,我试着自己做,它没问题,工作很好,但它慢得令人无法忍受,不像prt scr键-我想知道是否有一种方法可以访问prt scr剪贴板,并以某种方式粘贴在jpg/png文件或如果有更快的方法来获得所有的屏幕像素。这是我的代码:

  1. int main()
  2. {
  3. bitmap_t pic;
  4. int i, j;
  5. pic.width = GetSystemMetrics(SM_CXSCREEN);
  6. pic.height = GetSystemMetrics(SM_CYSCREEN);
  7. pic.pixels = (pixel_t**)malloc(sizeof(pixel_t*)*pic.width);
  8. for(i = 0 ; i < pic.height ; i++)
  9. {
  10. pic.pixels[i] = (pixel_t*)malloc(sizeof(pixel_t)*pic.height);
  11. }
  12. HDC hdc = GetDC(NULL);
  13. COLORREF c;
  14. printf("Size of your monitor is %d by %d.\n", pic.width, pic.height);
  15. for(i = 0 ; i < pic.width ; i++)
  16. {
  17. for(j = 0 ; j < pic.height ; j++)
  18. {
  19. c = GetPixel(hdc, i, j);
  20. pic.pixels[i][j].red = (uint8_t)GetRValue(c);
  21. pic.pixels[i][j].green = (uint8_t)GetGValue(c);
  22. pic.pixels[i][j].blue = (uint8_t)GetBValue(c);
  23. }
  24. }
  25. ReleaseDC(NULL, hdc);
  26. save_png_to_file(&pic, "D:\\pic.png");
  27. for(i = 0 ; i < pic.height ; i++)
  28. {
  29. free(pic.pixels[i]);
  30. }
  31. free(pic.pixels);
  32. return 0;
  33. }

字符串
函数save_png_to_file工作正常,循环时间太长(我的屏幕是1366 x768,超过百万个循环条目)-为什么当键prt scr轻松完成时,它会这么慢?

64jmpszr

64jmpszr1#

嗯. GetPixel()本身真的很慢,然后将它结合在一个循环中,并进行多次重复.

  1. BOOL SaveToFile(HBITMAP hBitmap3, LPCTSTR lpszFileName)
  2. {
  3. HDC hDC;
  4. int iBits;
  5. WORD wBitCount;
  6. DWORD dwPaletteSize=0, dwBmBitsSize=0, dwDIBSize=0, dwWritten=0;
  7. BITMAP Bitmap0;
  8. BITMAPFILEHEADER bmfHdr;
  9. BITMAPINFOHEADER bi;
  10. LPBITMAPINFOHEADER lpbi;
  11. HANDLE fh, hDib, hPal,hOldPal2=NULL;
  12. hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
  13. iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
  14. DeleteDC(hDC);
  15. if (iBits <= 1)
  16. wBitCount = 1;
  17. else if (iBits <= 4)
  18. wBitCount = 4;
  19. else if (iBits <= 8)
  20. wBitCount = 8;
  21. else
  22. wBitCount = 24;
  23. GetObject(hBitmap3, sizeof(Bitmap0), (LPSTR)&Bitmap0);
  24. bi.biSize = sizeof(BITMAPINFOHEADER);
  25. bi.biWidth = Bitmap0.bmWidth;
  26. bi.biHeight =-Bitmap0.bmHeight;
  27. bi.biPlanes = 1;
  28. bi.biBitCount = wBitCount;
  29. bi.biCompression = BI_RGB;
  30. bi.biSizeImage = 0;
  31. bi.biXPelsPerMeter = 0;
  32. bi.biYPelsPerMeter = 0;
  33. bi.biClrImportant = 0;
  34. bi.biClrUsed = 256;
  35. dwBmBitsSize = ((Bitmap0.bmWidth * wBitCount +31) & ~31) /8
  36. * Bitmap0.bmHeight;
  37. hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));
  38. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
  39. *lpbi = bi;
  40. hPal = GetStockObject(DEFAULT_PALETTE);
  41. if (hPal)
  42. {
  43. hDC = GetDC(NULL);
  44. hOldPal2 = SelectPalette(hDC, (HPALETTE)hPal, FALSE);
  45. RealizePalette(hDC);
  46. }
  47. GetDIBits(hDC, hBitmap3, 0, (UINT) Bitmap0.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
  48. +dwPaletteSize, (BITMAPINFO *)lpbi, DIB_RGB_COLORS);
  49. if (hOldPal2)
  50. {
  51. SelectPalette(hDC, (HPALETTE)hOldPal2, TRUE);
  52. RealizePalette(hDC);
  53. ReleaseDC(NULL, hDC);
  54. }
  55. fh = CreateFile(lpszFileName, GENERIC_WRITE,0, NULL, CREATE_ALWAYS,
  56. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  57. if (fh == INVALID_HANDLE_VALUE)
  58. return FALSE;
  59. bmfHdr.bfType = 0x4D42; // "BM"
  60. dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;
  61. bmfHdr.bfSize = dwDIBSize;
  62. bmfHdr.bfReserved1 = 0;
  63. bmfHdr.bfReserved2 = 0;
  64. bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;
  65. WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
  66. WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);
  67. GlobalUnlock(hDib);
  68. GlobalFree(hDib);
  69. CloseHandle(fh);
  70. return TRUE;
  71. }
  72. int screenCapture(int x, int y, int w, int h, LPCSTR fname)
  73. {
  74. HDC hdcSource = GetDC(NULL);
  75. HDC hdcMemory = CreateCompatibleDC(hdcSource);
  76. int capX = GetDeviceCaps(hdcSource, HORZRES);
  77. int capY = GetDeviceCaps(hdcSource, VERTRES);
  78. HBITMAP hBitmap = CreateCompatibleBitmap(hdcSource, w, h);
  79. HBITMAP hBitmapOld = (HBITMAP)SelectObject(hdcMemory, hBitmap);
  80. BitBlt(hdcMemory, 0, 0, w, h, hdcSource, x, y, SRCCOPY);
  81. hBitmap = (HBITMAP)SelectObject(hdcMemory, hBitmapOld);
  82. DeleteDC(hdcSource);
  83. DeleteDC(hdcMemory);
  84. HPALETTE hpal = NULL;
  85. if(SaveToFile(hBitmap, fname)) return 1;
  86. return 0;
  87. }
  88. int main()
  89. {
  90. screenCapture(0, 0, GetSystemMetric, 768, "D:\\MyFirstScreeshot.bmp");
  91. return 0;
  92. }

字符串

展开查看全部
x3naxklr

x3naxklr2#

这是在这里解释:
http://msdn.microsoft.com/en-us/library/dd183402(v=vs.85).aspx
请参阅示例中的CaptureAnImage()函数。整个代码有点复杂,因为它是一个完整的win32应用程序,但它显示了如何捕获特定窗口并保存到filename.bmp

相关问题