C++ libVNC开源库

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

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <rfb/rfbclient.h>
#include <rfb/rfb.h>
#include <png.h>

void saveScreenshot(rfbClient* client, const char* filename) {
    std::cout << "Entering saveScreenshot function..." << std::endl;

    int width = client->width;
    int height = client->height;
    std::cout << "Dimensions: " << width << "x" << height << std::endl;

    FILE *fp = fopen(filename, "wb");
    if (!fp) {
        std::cerr << "Failed to open file for writing!" << std::endl;
        return;
    }

    png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    png_infop info_ptr = png_create_info_struct(png_ptr);
    std::cout << "PNG structures initialized..." << std::endl;

    png_init_io(png_ptr, fp);
    png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB,
                 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

    png_byte** rows = (png_byte**)malloc(height * sizeof(png_byte*));

    std::cout << "Processing pixels..." << std::endl;
    for (int y = 0; y < height; y++) {
        rows[y] = (png_byte*)malloc(3 * width * sizeof(png_byte));
        for (int x = 0; x < width; x++) {
            uint16_t pixel = ((uint16_t*)client->frameBuffer)[y * width + x];

            uint8_t r = (pixel >> 10) & 0x1F;  // 5 bits red
            uint8_t g = (pixel >> 5) & 0x1F;   // 5 bits green
            uint8_t b = pixel & 0x1F;          // 5 bits blue

            // Convert from 5 bits to 8 bits
            rows[y][x*3] = (r << 3) | (r >> 2);
            rows[y][x*3+1] = (g << 3) | (g >> 2);
            rows[y][x*3+2] = (b << 3) | (b >> 2);
        }
    }

    std::cout << "Writing PNG..." << std::endl;
    png_set_rows(png_ptr, info_ptr, rows);
    png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);

    for (int y = 0; y < height; y++) {
        free(rows[y]);
    }
    free(rows);
    png_destroy_write_struct(&png_ptr, &info_ptr);
    fclose(fp);

    std::cout << "Exiting saveScreenshot function..." << std::endl;
}

rfbBool resize(rfbClient* client) {
    int width = client->width;
    int height = client->height;
    std::cout << "Resized to " << width << "x" << height << std::endl;
    client->frameBuffer = (uint8_t*)realloc(client->frameBuffer, width * height * client->format.bitsPerPixel / 8);
    return TRUE;
}

char* get_password(rfbClient* client) {
    return strdup("Ls1020..");
}

bool framebufferUpdated = false;
static void frameBufferUpdateCallback(rfbClient* client, int x, int y, int w, int h) {
    static time_t t=0,t1;
    FILE* f;
    int i,j;
    rfbPixelFormat* pf=&client->format;
    int bpp=pf->bitsPerPixel/8;
    int row_stride=client->width*bpp;

    t1=time(NULL);
    if(t1-t>2)
        t=t1;
    else
        return;

    if(bpp!=4 && bpp!=2) {
        rfbClientLog("bpp = %d (!=4)\n",bpp);
        return;
    }

    f=fopen("framebuffer.ppm","wb");
    if(!f) {
        rfbClientErr("Could not open framebuffer.ppm\n");
        return;
    }

    fprintf(f,"P6\n# %s\n%d %d\n255\n",client->desktopName,client->width,client->height);
    for(j=0;j<client->height*row_stride;j+=row_stride)
        for(i=0;i<client->width*bpp;i+=bpp) {
            unsigned char* p=client->frameBuffer+j+i;
            unsigned int v;
            if(bpp==4)
                v=*(unsigned int*)p;
            else if(bpp==2)
                v=*(unsigned short*)p;
            else
                v=*(unsigned char*)p;
            fputc((v>>pf->redShift)*256/(pf->redMax+1),f);
            fputc((v>>pf->greenShift)*256/(pf->greenMax+1),f);
            fputc((v>>pf->blueShift)*256/(pf->blueMax+1),f);
        }
    fclose(f);

    framebufferUpdated = true;
}

int main(int argc, char *argv[]){
    rfbClient* client = rfbGetClient(8, 3, 4);
    client->MallocFrameBuffer = resize;
    client->GetPassword = get_password;
    client->serverHost = strdup("42.48.206.82");
    client->serverPort = 5901;
    client->GotFrameBufferUpdate = frameBufferUpdateCallback;

    if (!rfbInitClient(client, nullptr, nullptr)) {
        std::cerr << "Failed to initialize the client!" << std::endl;
        return 1;
    }

    // Request a full framebuffer update from the server
    std::cout << "Requesting framebuffer update..." << std::endl;
    SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE);

    std::cout << "Taking a screenshot..." << std::endl;
    time_t t = time(NULL);
    while (time(NULL)-t<50 && !framebufferUpdated) {
        int n = WaitForMessage(client,50);
        if(n < 0){
            // client->socket==-1
            break;
        }

        if (n==0){
            // no message from server
        }

        if(n){
            // handle message from server
            if(!HandleRFBServerMessage(client))
                break;
        }
    }

    if (framebufferUpdated){
        saveScreenshot(client, "screenshot.png");
    }

    rfbClientCleanup(client);
    return 0;
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值