Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

A MySQL Connector/C++ is needed and is out of scope here... but... because the setBlob() MySql API works with std::istream (see here) my answer shows how to serialize a cv::Mat into a std::istream.

Helper struct for later use

struct matInfo
{
    matInfo(int _cols = -1, int _rows = -1, int _type = CV_8U) :
        cols(_cols), rows(_rows), type(_type){};
    int cols, rows, type;
    size_t Size() {return CV_ELEM_SIZE(type) * rows * cols;}
    size_t RowSize(){ return CV_ELEM_SIZE(type) * cols; }
};

Write cv::Mat to std::ostream

bool MatSerialize(ostream &out, const Mat& mat)
{
    matInfo mi( mat.cols, mat.rows, mat.type() );
    std::ostream::sentry s(out);
    if (!(s && out.good()))
        return false;
    out.write((char*)(&mi), sizeof(matInfo));
    if (mat.isContinuous())
        out.write((char*)mat.data, mi.Size());
    else
    {
        size_t rowsz = mi.RowSize();
        for (int r = 0; r < mi.rows; ++r)
            out.write((char*)mat.ptr<char>(r), rowsz);
    }
    out.flush();
    return out.good();
}
/** \brief Useful stream operator. stringstream is used to avoid conflict with cv::operator<< */
stringstream& operator<< (stringstream &out, const cv::Mat& mat)
{
    MatSerialize(out, mat);
    return out;
}

Your main

...
mat= imread("Lena.jpg");
//serialize cv::Mat. stringstream is need if stream operator is used
std::stringstream ss;
ss << mat;// or call MatSerialize(ss, mat);

//map an input stream over our buffer
std::istream is(ss.rdbuf());

//call the MySql API on a valid statement like below
stmt->setBlob(pos, &is);

to get back a cv::Mat from a stream the de-serialization is needed

/** \brief Decode a cv::mat from istream*/
bool MatDeserialize(std::istream& in, cv::Mat& mat)
{
    std::istream::sentry s(in);
    if (!(s && in.good()))
    {
        mat = Mat();
        return false;
    }
    matInfo mi;
    in.read((char*)(&mi), sizeof(matInfo));
    if (mi.Size() < 0)
    {
        mat = Mat();
        return false;
    }
    mat = Mat(mi.rows, mi.cols, mi.type);
    in.read((char*)mat.data, mi.Size());
    return in.good();
}
/** \brief Useful stream operator*/
istream& operator>>(std::istream& in, cv::Mat& mat)
{
    MatDeserialize(in, mat);
    return in;
}

and use it in your main as below

// deserialize (get back) the image
Mat mat2;
is >> mat2; //or call MatDeserialize(is,mat2)

it should works with all image format/pixel type