raw bitmap data to jpeg or png C++

11,208

In order to convert between image formats, the easiest way would be using the class CImage shared by MFC and ATL and defined in the header file atlimage.h.

CImage image; 
HRESULT res = image.Load("in.bmp");
image.Save("out.jpg");
image.Save("out.gif");
image.Save("out.png");
image.Save("out.tif");





If you have a RGB buffer and want to create a bitmap: just create and save a bitmap header into a file and add the RGB buffer to it.

To create the header you can use the BITMAPFILEHEADER, BITMAPINFOHEADER and RGBQUAD structures from GDI defined in the header WinGDI.h

Here is an example on how to fill the header data:

BITMAPINFOHEADER bmpInfoHdr;

bmpInfoHdr.biSize = sizeof(BITMAPINFOHEADER);
bmpInfoHdr.biHeight = nHeight;
bmpInfoHdr.biWidth =  nWidthPadded;
bmpInfoHdr.biPlanes = 1;
bmpInfoHdr.biBitCount = bitsPerPixel;           
bmpInfoHdr.biSizeImage = nHeight * nWidthPadded * nSPP; 
bmpInfoHdr.biCompression =  BI_RGB; 
bmpInfoHdr.biClrImportant = 0;  
bmpInfoHdr.biClrUsed = 0;
bmpInfoHdr.biXPelsPerMeter = 0;
bmpInfoHdr.biYPelsPerMeter = 0;
bmpFileHdr.bfType = BITMAP_FORMAT_BMP;
bmpFileHdr.bfSize =  (DWORD) (sizeof(BITMAPFILEHEADER) + bmpInfoHdr.biSize +
                      sizeof(RGBQUAD)*numColors + bmpInfoHdr.biSizeImage);
bmpFileHdr.bfReserved1 = 0;
bmpFileHdr.bfReserved2 = 0;
bmpFileHdr.bfOffBits = (DWORD) (sizeof(BITMAPFILEHEADER) + bmpInfoHdr.biSize + 
                        sizeof(RGBQUAD)*numColors);


Keep into account that the bitmaps are stored upside-down and that the width of the image must be aligned on a DWORD except for RLE-compressed bitmaps.(they must be multiple of 4 bytes, add a padding if necessary).

if ((nWidth%4) != 0)
    nPadding = ((nWidth/4) + 1) * 4;

When saving your buffer, add the needed padding to each row...


Summarizing, these are the needed steps to create a bitmap file from a rgb buffer:

//1. create bmp header 

//2. save header to file:
 write(file, &bmpFileHdr, sizeof(BITMAPFILEHEADER));
 write(file, &bmpInfoHdr, sizeof(BITMAPINFOHEADER));
 write(file, &colorTable, numColors * sizeof(RGBQUAD));

//3. add rgb buffer to file:
for(int h=0; h<nHeight; h++) {
   for(int w=0; w<nWidth; w++) {
      //3.a) add row to file
      //3.b) add padding for this row to file
   }
}
Share:
11,208
dmigous
Author by

dmigous

Updated on June 04, 2022

Comments

  • dmigous
    dmigous almost 2 years

    I have bytearray where every three bytes describes 1 pixel (RGB). The task is to convert it to jpeg or png.

    Actually, I am using Zint (open source lib for generating barcodes) that uses libpng to generate image file and save it to file system, but in Zintthe function png_plot() except generating image also save it on disk which is undesirable.

    As result I think there two ways:
    1. from bitmap bytearray to bmp -> jpeg / png (using some other lib)
    2. writing hook or some similar to png_plot()

    Can you give me some advices? Thank you.

    Upd: for @peacemaker

    
    FILE *f;
    zint_symbol *my_symbol;
    my_symbol = ZBarcode_Create();
    ZBarcode_Encode_and_Buffer(my_symbol, (unsigned char *)argv[1], 0, 0);
    f = fopen("bitmap.bmp", "w");
    fwrite(my_symbol->bitmap, sizeof(*(my_symbol->bitmap)), my_symbol->bitmap_height * my_symbol->bitmap_width, f);
    ZBarcode_Delete(my_symbol);
    fclose(f);