I have a library that takes screen capture data GitHub - smasherprog/screen_capture_lite: cross platform screen/window capturing library
I want to take Screen Capture Lite’s Screen_Capture::Image
and translate it to a cv::Mat
or std::vector<std::uint8_t> buffer
it sounds like I could use cv::imencode()
for this… but having trouble understanding how to switch from encoding files via imread()
to this RGB array… ScreenCapture Lite gives an extraction example… but I am unclear how to translate what they’re doing… to what OpenCV wants / needs … so that the client can decode on the other side
void ExtractAndConvertToJPGBuffer(const SL::Screen_Capture::Image &img, std::vector<std::uint8_t> *dst, size_t dst_size)
{
assert(dst_size >= static_cast<size_t>(SL::Screen_Capture::Width(img) * SL::Screen_Capture::Height(img) * sizeof(SL::Screen_Capture::ImageBGRA)));
auto imgsrc = StartSrc(img);
auto size = Width(img) * Height(img) * sizeof(SL::Screen_Capture::ImageBGRA);
auto imgbuffer(std::make_unique<unsigned char[]>(size));
auto imgdist = unsigned char *dst;
if (img.isContiguous) {
memcpy(imgdist, imgsrc, dst_size);
}
else {
for (auto h = 0; h < Height(img); h++) {
auto startimgsrc = imgsrc;
for (auto w = 0; w < Width(img); w++) {
*imgdist++ = imgsrc->R;
*imgdist++ = imgsrc->G;
*imgdist++ = imgsrc->B;
imgsrc++;
}
imgsrc = SL::Screen_Capture::GotoNextRow(img, startimgsrc);
}
}
cv::Mat image;
std::vector<int> param(2);
cv::imencode(".jpg", imgsrc, &dst, param);
}
For those curious, the Server Client relationship looks like this. I’ve already gotten this to work with file based JPEGS… just now needing to switch from that… to this SL::Screen_Capture::Image
. … biggest clue I have so far is it sounds quite close to InputArray
… but one seems to be an unsigned char
the other is unclear, their example uses auto
which hides what data type this is
.
.
.
Client.cpp
std::vector<std::uint8_t> buff(header_data.image_size_bytes);
boost::asio::read(socket, boost::asio::buffer(buff), boost::asio::transfer_exactly(header_data.image_size_bytes), ignored_error);
cv::Mat img(cv::imdecode(buff, cv::IMREAD_ANYCOLOR));
Server.cpp
void transmitsocketdata(tcp::socket & socket, const SL::Screen_Capture::Image & screen_cap_img){
boost::system::error_code ignored_error;
std::vector<std::uint8_t> buff;
ExtractAndConvertToJPGBuffer(screen_cap_img, &buff)
// now we send the header message
std::string image_dimensions = std::to_string(Width(screen_cap_img)) + "Wx" + std::to_string(Height(screen_cap_img)) + "H";
std::string image_buff_bytes = std::to_string(buff.size());
std::string message_header = image_dimensions + "," + image_buff_bytes;
message_header.append(63 - message_header.length(), ' ');
message_header = message_header + '\0';
std::cout << "sending message header == " << message_header << " ...." << std::endl;
std::cout << "sending message header of " << std::to_string(message_header.length()) << " bytes...." << std::endl;
socket.write_some(boost::asio::buffer(message_header), ignored_error);
std::cout << "sending image message of " << image_buff_bytes << " bytes...." << std::endl;
socket.write_some(boost::asio::buffer(buff), ignored_error);
}