当前位置:   article > 正文

C++ libVNC开源库

C++ libVNC开源库

VNC具体用途,不用过多介绍了。这里只简单写一个获取服务器端画面的示例:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <cstdlib>
  5. #include <unistd.h>
  6. #include <rfb/rfbclient.h>
  7. #include <rfb/rfb.h>
  8. #include <png.h>
  9. void saveScreenshot(rfbClient* client, const char* filename) {
  10. std::cout << "Entering saveScreenshot function..." << std::endl;
  11. int width = client->width;
  12. int height = client->height;
  13. std::cout << "Dimensions: " << width << "x" << height << std::endl;
  14. FILE *fp = fopen(filename, "wb");
  15. if (!fp) {
  16. std::cerr << "Failed to open file for writing!" << std::endl;
  17. return;
  18. }
  19. png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  20. png_infop info_ptr = png_create_info_struct(png_ptr);
  21. std::cout << "PNG structures initialized..." << std::endl;
  22. png_init_io(png_ptr, fp);
  23. png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB,
  24. PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
  25. png_byte** rows = (png_byte**)malloc(height * sizeof(png_byte*));
  26. std::cout << "Processing pixels..." << std::endl;
  27. for (int y = 0; y < height; y++) {
  28. rows[y] = (png_byte*)malloc(3 * width * sizeof(png_byte));
  29. for (int x = 0; x < width; x++) {
  30. uint16_t pixel = ((uint16_t*)client->frameBuffer)[y * width + x];
  31. uint8_t r = (pixel >> 10) & 0x1F; // 5 bits red
  32. uint8_t g = (pixel >> 5) & 0x1F; // 5 bits green
  33. uint8_t b = pixel & 0x1F; // 5 bits blue
  34. // Convert from 5 bits to 8 bits
  35. rows[y][x*3] = (r << 3) | (r >> 2);
  36. rows[y][x*3+1] = (g << 3) | (g >> 2);
  37. rows[y][x*3+2] = (b << 3) | (b >> 2);
  38. }
  39. }
  40. std::cout << "Writing PNG..." << std::endl;
  41. png_set_rows(png_ptr, info_ptr, rows);
  42. png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
  43. for (int y = 0; y < height; y++) {
  44. free(rows[y]);
  45. }
  46. free(rows);
  47. png_destroy_write_struct(&png_ptr, &info_ptr);
  48. fclose(fp);
  49. std::cout << "Exiting saveScreenshot function..." << std::endl;
  50. }
  51. rfbBool resize(rfbClient* client) {
  52. int width = client->width;
  53. int height = client->height;
  54. std::cout << "Resized to " << width << "x" << height << std::endl;
  55. client->frameBuffer = (uint8_t*)realloc(client->frameBuffer, width * height * client->format.bitsPerPixel / 8);
  56. return TRUE;
  57. }
  58. char* get_password(rfbClient* client) {
  59. return strdup("Ls1020..");
  60. }
  61. bool framebufferUpdated = false;
  62. static void frameBufferUpdateCallback(rfbClient* client, int x, int y, int w, int h) {
  63. static time_t t=0,t1;
  64. FILE* f;
  65. int i,j;
  66. rfbPixelFormat* pf=&client->format;
  67. int bpp=pf->bitsPerPixel/8;
  68. int row_stride=client->width*bpp;
  69. t1=time(NULL);
  70. if(t1-t>2)
  71. t=t1;
  72. else
  73. return;
  74. if(bpp!=4 && bpp!=2) {
  75. rfbClientLog("bpp = %d (!=4)\n",bpp);
  76. return;
  77. }
  78. f=fopen("framebuffer.ppm","wb");
  79. if(!f) {
  80. rfbClientErr("Could not open framebuffer.ppm\n");
  81. return;
  82. }
  83. fprintf(f,"P6\n# %s\n%d %d\n255\n",client->desktopName,client->width,client->height);
  84. for(j=0;j<client->height*row_stride;j+=row_stride)
  85. for(i=0;i<client->width*bpp;i+=bpp) {
  86. unsigned char* p=client->frameBuffer+j+i;
  87. unsigned int v;
  88. if(bpp==4)
  89. v=*(unsigned int*)p;
  90. else if(bpp==2)
  91. v=*(unsigned short*)p;
  92. else
  93. v=*(unsigned char*)p;
  94. fputc((v>>pf->redShift)*256/(pf->redMax+1),f);
  95. fputc((v>>pf->greenShift)*256/(pf->greenMax+1),f);
  96. fputc((v>>pf->blueShift)*256/(pf->blueMax+1),f);
  97. }
  98. fclose(f);
  99. framebufferUpdated = true;
  100. }
  101. int main(int argc, char *argv[]){
  102. rfbClient* client = rfbGetClient(8, 3, 4);
  103. client->MallocFrameBuffer = resize;
  104. client->GetPassword = get_password;
  105. client->serverHost = strdup("42.48.206.82");
  106. client->serverPort = 5901;
  107. client->GotFrameBufferUpdate = frameBufferUpdateCallback;
  108. if (!rfbInitClient(client, nullptr, nullptr)) {
  109. std::cerr << "Failed to initialize the client!" << std::endl;
  110. return 1;
  111. }
  112. // Request a full framebuffer update from the server
  113. std::cout << "Requesting framebuffer update..." << std::endl;
  114. SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE);
  115. std::cout << "Taking a screenshot..." << std::endl;
  116. time_t t = time(NULL);
  117. while (time(NULL)-t<50 && !framebufferUpdated) {
  118. int n = WaitForMessage(client,50);
  119. if(n < 0){
  120. // client->socket==-1
  121. break;
  122. }
  123. if (n==0){
  124. // no message from server
  125. }
  126. if(n){
  127. // handle message from server
  128. if(!HandleRFBServerMessage(client))
  129. break;
  130. }
  131. }
  132. if (framebufferUpdated){
  133. saveScreenshot(client, "screenshot.png");
  134. }
  135. rfbClientCleanup(client);
  136. return 0;
  137. }

如果需要实时更新服务器端画面,while循环就可以了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/430061
推荐阅读
相关标签
  

闽ICP备14008679号