How to read image files and store them in memory (std :: string) in C ++?

I researched online for most of today, but couldn't find an answer, so I turn to stackoverflow for some suggestion.

Basically, I have a C ++ library that uses curl to execute the PUT method to load an image file. now this library accepts std :: string for data. I have image files (e.g. jpg, gif, png) on โ€‹โ€‹my local drive.

I donโ€™t care about the contents of the file (like in, I do nothing with it except passing it to this library for the PUT method). How can I read image files and store them in std :: string? What if the contents of the file contain a null terminator?

I tried to add some of the codes that I tried, but I'm new here, and I'm not sure how to paste my code here in the correct format. Any help would be appreciated.

+6
source share
3 answers

The easiest way I can think of. Open the file in binary mode, then read it all in stringstream .

 std::ifstream fin("foo.png", std::ios::in | std::ios::binary); std::ostringstream oss; oss << fin.rdbuf(); std::string data(oss.str()); 
+4
source
 std::ifstream fin("foo.png", std::ios::binary); std::string data; data.reserve(1000000); std::copy(std::istreambuf_iterator<char>(fin), std::istreambuf_iterator<char>(), std::back_inserter(data)); 

You can read image files with std::string with this code. Adjust the parameter for the reserve method to more than 99% of the size of your file. Zero bytes (which you call NULL terminators) are handled correctly with both ifstream and string .


I found a good article comparing several binary file loading methods. Here is the fastest way from this article:

 std::ifstream fin("foo.png", std::ios::binary); fin.seekg(0, std::ios::end); std::string data; data.resize(fin.tellg()); fin.seekg(0, std::ios::beg); fin.read(&data[0], data.size()); 

And here is the shortest:

 std::ifstream fin("foo.png", std::ios::binary); std::string data((std::istreambuf_iterator<char>(fin)), std::istreambuf_iterator<char>()); 

Update

Something like this can be used to provide a callback function (I have not tested it):

 std::ifstream fin("foo.png", std::ios::binary); fin.seekg(0, std::ios::end); ... curl_easy_setopt(m_ctx, CURLOPT_INFILESIZE, fin.tellg()); curl_easy_setopt(m_ctx, CURLOPT_READDATA, (void *)&fin); fin.seekg(0, std::ios::beg); ... static size_t put_callback(void *ptr, size_t size, size_t nmemb, void *data){ std::ifstream* in = static_cast<std::ifstream*>(data); if(in->eof()) return 0; in->read((char *)ptr, size*nmemb); return in->gcount(); } 
+2
source

this is how the library makes PUT calls, where "data" is the string passed as the contents of the file

 stringstream data_stream.str(data.c_str()); curl_easy_setopt(m_ctx, CURLOPT_UPLOAD, 1L); curl_easy_setopt(m_ctx, CURLOPT_PUT, 1L); curl_easy_setopt(m_ctx, CURLOPT_INFILESIZE, data.length()); curl_easy_setopt(m_ctx, CURLOPT_READFUNCTION, put_callback); curl_easy_setopt(m_ctx, CURLOPT_READDATA, (void *)&data_stream); curl_easy_setopt(m_ctx, CURLOPT_WRITEFUNCTION, get_callback); curl_easy_setopt(m_ctx, CURLOPT_WRITEDATA, (void *)&m_request_response); 

and here the callback function for curlopt_readfunction is used

 static size_t put_callback(void *ptr, size_t size, size_t nmemb, void *data){ stringstream *output_stream; int retval; output_stream = (stringstream *) data; if(output_stream->eof()) return 0; retval = min(size*nmemb,output_stream->str().size()); output_stream->read((char *)ptr, retval); //return the number of bytes processed return retval; } 
+2
source

Source: https://habr.com/ru/post/910220/


All Articles