BOOSTでOpenCVのMat型をPOSTする
BOOSTでMat型の画像をHTMLのbodyに乗せてPOSTする。 base64にエンコードするためにto_base64を使う点だけにC++RESTSDKを使った。 今回はVisualStudioで開発する必要があったたため、NuGetで Boostと C++RESTSDKを ダウンロードした。C++RESTSDKはNuGetでCasablancaで検索。
#include <iostream> #include <istream> #include <ostream> #include <string> #include <boost/asio.hpp> #include <opencv2/opencv.hpp> #include <Windows.h> #include <sstream> #include <fstream> #include <iostream> #include <vector> #include <cpprest/http_client.h> #include<cpprest/filestream.h> #include <locale> #include <codecvt> #include <cstdio> #pragma comment (lib, "opencv_world310d.lib") using boost::asio::ip::tcp; using namespace cv; using namespace std; using namespace web; using namespace web::http; using namespace web::http::client; using namespace utility::conversions; int main(int argc, char* argv[]) { Mat input = imread("banana_3.jpg"); vector<uchar> buff; static int64 startTick, endTick, diffTick; startTick = getTickCount(); imencode(".jpg", input, buff); wstring ws = to_base64(buff); wstring_convert<codecvt_utf8<wchar_t>, wchar_t> cv; string s = cv.to_bytes(ws); size_t sizeInBytes = s.size(); try { boost::asio::io_service io_service; tcp::resolver resolver(io_service); tcp::resolver::query query("133.34.174.126", "5000"); tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); tcp::socket socket(io_service); boost::asio::connect(socket, endpoint_iterator); boost::asio::streambuf request; std::ostream request_stream(&request); request_stream << "POST " << "http://133.34.174.126:5000/upload" << " HTTP/1.1\r\n"; request_stream << "Host: " << "133.34.174.126" << "\r\n"; request_stream << "Accept: */*\r\n"; request_stream << "Connection: close\r\n"; request_stream << "Content-Type: application/octet-stream\r\n"; request_stream << "Content-Length: " << sizeInBytes << "\r\n"; request_stream << "\r\n"; request_stream << s << "\r\n"; // Send the request. boost::asio::write(socket, request); // Read the response status line. The response streambuf will automatically // grow to accommodate the entire line. The growth may be limited by passing // a maximum size to the streambuf constructor. boost::asio::streambuf response; boost::asio::read_until(socket, response, "\r\n"); // Check that response is OK. std::istream response_stream(&response); std::string http_version; response_stream >> http_version; unsigned int status_code; response_stream >> status_code; std::string status_message; std::getline(response_stream, status_message); if (!response_stream || http_version.substr(0, 5) != "HTTP/") { std::cout << "Invalid response\n"; return 1; } if (status_code != 200) { std::cout << "Response returned with status code " << status_code << "\n"; return 1; } // Read the response headers, which are terminated by a blank line. boost::asio::read_until(socket, response, "\r\n\r\n"); // Process the response headers. std::string header; while (std::getline(response_stream, header) && header != "\r") std::cout << header << "\n"; std::cout << "\n"; // Write whatever content we already have to output. if (response.size() > 0) std::cout << &response; // Read until EOF, writing data to output as we go. boost::system::error_code error; while (boost::asio::read(socket, response, boost::asio::transfer_at_least(1), error)) std::cout << &response; if (error != boost::asio::error::eof) throw boost::system::system_error(error); } catch (std::exception& e) { std::cout << "Exception: " << e.what() << "\n"; } endTick = getTickCount(); diffTick = endTick - startTick; double msec = 1000.0 * (diffTick / getTickFrequency()); cout << msec << endl; system("PAUSE"); return 0; }