c++ - 屏幕截图创建和上传

标签 c++ image image-processing dev-c++

我正在尝试编写一个图片上传客户端。我使用这段代码抓取屏幕截图并将其写入变量 hBitmap。然后我想使用此代码下的代码上传它,但我不知道如何转换或重新格式化图像。我不想将图像写入文件然后读出文件,那样很容易 ;)

// get the device context of the screen
HDC hScreenDC = CreateDC("DISPLAY", NULL, NULL, NULL);     
// and a device context to put it in
HDC hMemoryDC = CreateCompatibleDC(hScreenDC);

int x = GetDeviceCaps(hScreenDC, HORZRES);
int y = GetDeviceCaps(hScreenDC, VERTRES);

// maybe worth checking these are positive values
HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDc, x, y);

// get a new bitmap
HBITMAP hOldBitmap = SelectObject(hMemoryDC, hBitmap);

BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY);
hBitmap = SelectObject(hMemoryDC, hOldBitmap);

// clean up
DeleteDC(hMemoryDC);
DeleteDC(hScreenDC);

这是我的上传代码:

void HTTP_UPLOAD_REQUEST(char * Server,int Port,char * uploadscript,char* boundary,char*filetoup,char* data)
{
//Create Socket for sending data
WSADATA wsaData;
WSAStartup( MAKEWORD( 1,1 ), &wsaData );
SOCKET Socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
LPHOSTENT hostEntry;
hostEntry = gethostbyname( Server );//Get ip from Server by hostname
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr = *((LPIN_ADDR)*hostEntry->h_addr_list);
addr.sin_port = htons( Port ); //Set Port
connect( Socket, (LPSOCKADDR) &addr, sizeof(struct sockaddr) );
//Socket created and connected to Server!

//Create HTTP POST Request
//construct POST Header
char header[512]="";
sprintf( header, "POST %s HTTP/1.0\r\nContent-Type: multipart/form-data; boundary=%s\r\nContent-Length: %u\r\n\r\n",uploadscript, boundary,2*strlen(data));

//construct Body(data part) of HTTP POST
char* body=new char[strlen(data)+4000];
sprintf( body, "--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n\r\n %s\r\n--%s\r\n",boundary,"data",filetoup,data,boundary);

//Put Header and Body together into Request
char * Request=new char[strlen(header)+strlen(body)+strlen(data)];
sprintf( Request, "%s%s", header,body );

//int bytestosend = strlen(Request);
int bytessend =send( Socket, Request, strlen(Request), 0 ); 


closesocket(Socket);//cleanup -!

}

最佳答案

  1. 您现在拥有的是原始位图数据。有效的位图 (*.bmp) 文件还必须包含 BMP header 。有个好article关于它。

    也许那时您想将巨大的 bmp 文件转换为 jpeg 或 png 格式。 Free image ,例如,能够执行这种内存中转换。

  2. 如果您需要将数据上传到网络,请考虑使用一些可靠的网络库,例如 libcurl .您的实现存在一些内存泄漏。

    我还建议尽可能使用 std::stringstd::vector。它不仅为您提供了无泄漏,而且还提供了更好的代码:

    void HTTP_UPLOAD_REQUEST(std::string Server, unsigned short Port, std::string uploadscript, std::string boundary, std::string filetoup, std::string data)
    {
        ...
    
        std::stringstream out;
    
        out << "POST " << uploadscript << " HTTP/1.0\r\n";
        out << "Content-Type: multipart/form-data; boundary=" << boundary << "\r\n";
        out << "Content-Length: " << data.size();
    
        out << "--" << boundary << "\r\n";
        out << "Content-Disposition: form-data; name=\"data\"; filename=\""
            << filetoup << "\"\r\n\r\n";
    
        out << data << "\r\n--" << boundary << "\r\n";
    
        std::string toSend = out.str();
        int bytessend = send( Socket, toSend.c_str(), toSend.size(), 0 ); 
        ...
    }
    

    请注意,WSAStartup 必须在程序中只调用一次,而不是每次调用 HTTP_UPLOAD_REQUEST

关于c++ - 屏幕截图创建和上传,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19232751/

相关文章:

c++ - OpenCV C++ 中方差局部二进制模式 (VLBP) 的直方图计算

c++ - 用于标记未初始化变量的 VS 2008 编译器选项

c++ - 在文本文件中搜索短语 C++

c++ - 获取和设置函数与引用函数

php - 点击图片上传

c++ - 使用 OpenCV C++ 将多个图像叠加到相同大小的基本图像上

c++ - 哪种场景效率更高?

javascript - 如何加载多个文件图像作为数据 url 并在之后单独更改它们

java - 使用具有大数据的 ZXing 库生成条码时遇到问题

bash - 设置特定图像亮度