Search code examples
c++mysqlimageblob

get image dimension from blob column in MySQL database


I want to read image from a database, image column is a MYSQL_TYPE_BLOB type and I read column using this code. Currently, Blob image converted as a char * array

//Get the total number of fields
int fieldCount = mysql_num_fields(result);
    
//Get field information of a row of data
MYSQL_FIELD *fields = mysql_fetch_fields(result);

while (m_row = mysql_fetch_row(result))
{
    for (int i = 0;i < fieldCount; ++i)
    {
        if (fields[i].type == MYSQL_TYPE_BLOB)
        {
            unsigned long length = mysql_fetch_lengths(result)[i];
            char* buffer = new char[length + 1];
            memset(buffer, 0x00, sizeof(buffer));

            memcpy(buffer, m_row[i], length);
        }
    }   
}

In order to do some tests on image, I should know the image dimension without writing image on disk and reading it again?

Another way to read data from Mysql database is :

res = stmt->executeQuery("MY QUERY TO DATABASE");
while (res->next())
{
    std::istream *blobData = res->getBlob("image");
    std::istreambuf_iterator<char> isb = std::istreambuf_iterator<char>(*blobData);
    std::string blobString = std::string(isb, std::istreambuf_iterator<char>());
    tempFR.image = blobString;
    blobData->seekg(0, ios::end);
    tempFR.imageSize = blobData->tellg();

    std::istream *blobIn;
    char buffer[tempFR.imageSize];
    memset(buffer, '\0', tempFR.imageSize);
    blobIn = res->getBlob("image");
    blobIn->read((char*)buffer, tempFR.imageSize);
}

Notice:

imageSize and length are the overall image size, for example 1000.

Update#1: How image will be reconstruct meanwhile writing it to disk?

In the first case it's possible to write the blob_image to disk via this codes:

stringstream pic_name;
pic_name << "car.jpeg";
ofstream outfile(pic_name.str(), ios::binary);

outfile.write(buffer, length);

and in the second ones:

std::ofstream outfile ("car.jpeg",std::ofstream::binary);
outfile.write (buffer, tempFR.imageSize);
outfile.close();

In both cases image writed to disk correctly. But I want to find image dimension without writing it to disk and reading it again?


Solution

  • By decoding buffered image:

    length = mysql_fetch_lengths(result)[i];
    buffer = new char[length + 1];
    memset(buffer, 0x00, sizeof(buffer));
        
    memcpy(buffer, m_row[i], length);
        
    matImg = cv::imdecode(cv::Mat(1, length, CV_8UC1, buffer), cv::IMREAD_UNCHANGED);
    

    At first, copy array to buffer, then convert it to a cv::Mat and finally decode it. It will be a cv::Mat image.