c++base64jpegbgr

Convert BGR image into base64 string as jpeg


I have a color image represented in OpenCV convention where each pixel is represented as unsigned char in BGR order row after row:

const int BGR = 3;
const int rows= 256;
const int cols = 512;
unsigned char rawIm[BGR * rows *cols] = {'g', 't', 'y', // lots of chars.....}

I want to convert this stream into a base64 string which represents the corresponding jpeg image without actually writing the image on the disk, just "plain" bytes transformation. How can I do that in C++?


Solution

  • For the image to jpeg part, you can use toojpeg which is much easier to use than libjpeg. https://create.stephan-brumme.com/toojpeg/

    But you'll have to reverse the BGR to RGB first, because toojpeg does not support BGR yet.

    Here is an example:

    #include <vector>
    #include <string>
    #include <iostream>
    #include "toojpeg.h"
    
    std::vector<unsigned char> jpeg_data;
    
    void myOutput(unsigned char byte) {
        jpeg_data.push_back(byte);
    }
    
    int main() {
        const auto width = 800;
        const auto height = 600;
        const auto bytesPerPixel = 3;
    
        unsigned char bgr_data[width * height * bytesPerPixel];
    
        // put some sample data in bgr_data, just for the example
        for (unsigned i = 0; i < sizeof(bgr_data); i += 3) {
            bgr_data[i]     = i / width;
            bgr_data[i + 1] = i / width * 2;
            bgr_data[i + 2] = i / width * 3;
        }
    
        // convert BGR to RGB
        unsigned char rgb_data[sizeof(bgr_data)];
        for (unsigned i = 0; i < sizeof(bgr_data); i += 3) {
            rgb_data[i]     = bgr_data[i + 2];
            rgb_data[i + 1] = bgr_data[i + 1];
            rgb_data[i + 2] = bgr_data[i];
        }
    
        // convert the RGB data to jpeg
        bool isRGB = true;
        const auto quality = 90;
        const bool downsample = false;
        const char* comment = "example image";
        bool result_ok = TooJpeg::writeJpeg(myOutput, rgb_data, width, height, isRGB, quality, downsample, comment);
        if (result_ok) {
            // jpeg_data now contains jpeg-encoded image, which can be encoded as base 64
        }
        return 0;
    }