まだそんなことやってんの?

技術系備忘録ブログがメイン

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;
}