I am developing my own OS, with GNU-EFI, I am written a small BMP Image loader program.
I can Successfully read its headers and data ( not sure ) when I plot that on my Screen that is only showing blue color on pixels.
// Blue Pixels are Plotted BMP Image
How can I load this with Colours?
PlotPixel(x,y,color) Color takes Value as 0xFFFFFFFF;
Following is my bmp loader:
BMP.h
// bmp.h
#define WIN_BITMAP_SIGNATURE 0x4D42 // BM [ASCII]
#define BMP_HEADER_SIZE 54
#define DIB_HEADER_SIZE 40
#pragma pack(push, 1)
typedef struct
{
uint16_t bfType; // The characters "BM" - 2 Bytes
uint32_t bfSize; // The size of the file in bytes - 4 Bytes
uint16_t bfReserved1; // Unused - must be zero - 2 Bytes
uint16_t bfReserved2; // Unused - must be zero - 2 Bytes
uint32_t bfOffBits; // Offset to start of Pixel Data - 4 Bytes
uint32_t biSize; // DIB Header Size - 4 Bytes
int32_t biWidth; // Width - 4 Bytes
int32_t biHeight;
uint16_t biPlanes;
uint16_t biBitCount;
uint32_t biCompression;
uint32_t biSizeImage;
int32_t biXPexelsPerMeter;
int32_t biYPexelsPerMeter;
uint32_t biClrUsed;
uint32_t biClrImportant;
} BITMAP_HEADER;
typedef struct
{
BITMAP_HEADER* header;
uint8_t* data;
} BITMAP_IMG;
typedef struct
{
uint32_t red_mask;
uint32_t green_mask;
uint32_t blue_mask;
uint32_t alpha_mask;
uint32_t color_space_type;
uint32_t unused[16];
} BMPColorHeader;
#pragma pack(pop)
unsigned long createRGBA(int r, int g, int b, int a);
unsigned long createRGB(int r, int g, int b);
BITMAP_IMG* LoadBMPImage(EFI_FILE* Directory, CHAR16* Path, EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable);
BMP.c
// bmp.c
#include "bmp.h"
unsigned long createRGB(int r, int g, int b)
{
return ((r & 0xff) << 16) + ((g & 0xff) << 8) + (b & 0xff);
}
unsigned long createRGBA(int r, int g, int b, int a)
{
return ((r & 0xff) << 24) + ((g & 0xff) << 16) + ((b & 0xff) << 8)
+ (a & 0xff);
}
BITMAP_IMG* LoadBMPImage(EFI_FILE* Directory, CHAR16* Path, EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable)
{
EFI_FILE* BMPImage = LoadFile(Directory, Path, ImageHandle, SystemTable);
if(BMPImage == NULL) return NULL;
BITMAP_HEADER* BMPImageHeader;
SystemTable->BootServices->AllocatePool(EfiLoaderData, sizeof(BITMAP_HEADER), (void**)&BMPImageHeader);
UINTN size = sizeof(BITMAP_HEADER);
BMPImage->Read(BMPImage, &size, BMPImageHeader);
// Verify Signature
if(BMPImageHeader->bfType != WIN_BITMAP_SIGNATURE)
{
// Signature not Matched
Print(L"Signature Not Matched!");
Print(L"BMP Type [ Signature ] : ", BMPImageHeader->bfType);
return NULL;
}
else
{
Print(L"Signature Found");
}
if(BMPImageHeader->biBitCount == 32)
{
Print(L"BMP 32 Bit");
BMPColorHeader* BmpColor;
SystemTable->BootServices->AllocatePool(EfiLoaderData, sizeof(BMPColorHeader), (void**)&BmpColor);
UINTN size = sizeof(BITMAP_HEADER);
BMPImage->Read(BMPImage, &size, BmpColor);
// Check Color Header
if(0x00ff0000 != BmpColor->red_mask || 0x000000ff != BmpColor->blue_mask || 0x0000ff00 != BmpColor->green_mask)
{
Print(L"Unexpected Color Format");
}
if(0x73524742 != BmpColor->color_space_type)
{
Print(L"Unexcepted Color Space Type : %d", BmpColor->color_space_type);
}
}
else
{
Print(L"BMP Not 32 Bit : %d", BMPImageHeader->biBitCount);
}
uint8_t* BMPData;
{
BMPImage->SetPosition(BMPImage, sizeof(BITMAP_HEADER));
SystemTable->BootServices->AllocatePool(EfiLoaderData, size, (void**)&BMPData);
BMPImage->Read(BMPImage, &size, BMPData);
}
BITMAP_IMG* finishedImage;
SystemTable->BootServices->AllocatePool(EfiLoaderData, sizeof(BITMAP_IMG), (void**)&finishedImage);
finishedImage->header = BMPImageHeader;
finishedImage->data = BMPData;
int offset = 0;
int channels = finishedImage->header->biBitCount / 8;
for (int i = 0; i < finishedImage->header->biHeight; i++)
{
for (int j = 0; j < finishedImage->header->biWidth; j++)
{
//// I thinks following are wrong
// Red
int red = finishedImage->data[offset] & 0xFF;
int green = finishedImage->data[offset+1] & 0xFF;
int blue = finishedImage->data[offset+2] & 0xFF;
int alpha = 0x00;
// I thinks CreateRGBA can be also wrong
int hex_calculated = createRGBA(red, green, blue, alpha);
// This function is surely right ; It takes color value as 0xFFFFFFFF
PlotPixel(120+i, 120+j, hex_calculated);
offset += 3;
}
}
return finishedImage;
}
I am writing code to generate monochrome bmp image out of array. there are plenty of tools to generate bmp to array but i want it in reverse way. i found lots of code but it was color image.
here is code i am trying...
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <malloc.h>
#define _height 64
#define _width 128
#define _bitsperpixel 1
#define _planes 1
#define _compression 0
#define _pixelbytesize _height*_width*_bitsperpixel/8
#define _filesize _pixelbytesize+sizeof(bitmap)
#define _xpixelpermeter 0x130B //2835 , 72 DPI
#define _ypixelpermeter 0x130B //2835 , 72 DPI
#define pixel 0x55
#pragma pack(push,1)
unsigned char arr[8192]={0};
typedef struct{
uint8_t signature[2];
uint32_t filesize;
uint32_t reserved;
uint32_t fileoffset_to_pixelarray;
} fileheader;
typedef struct{
uint32_t dibheadersize;
uint32_t width;
uint32_t height;
uint16_t planes;
uint16_t bitsperpixel;
uint32_t compression;
uint32_t imagesize;
uint32_t ypixelpermeter;
uint32_t xpixelpermeter;
uint32_t numcolorspallette;
uint32_t mostimpcolor;
} bitmapinfoheader;
typedef struct {
fileheader fileheader;
bitmapinfoheader bitmapinfoheader;
} bitmap;
#pragma pack(pop)
int main (int argc , char *argv[]) {
int i;
FILE *fp = fopen("test.bmp","wb");
bitmap *pbitmap = (bitmap*)calloc(1,sizeof(bitmap));
uint8_t *pixelbuffer = (uint8_t*)malloc(_pixelbytesize);
strcpy(pbitmap->fileheader.signature,"BM");
pbitmap->fileheader.filesize = _filesize;
pbitmap->fileheader.fileoffset_to_pixelarray = sizeof(bitmap);
pbitmap->bitmapinfoheader.dibheadersize =sizeof(bitmapinfoheader);
pbitmap->bitmapinfoheader.width = _width;
pbitmap->bitmapinfoheader.height = _height;
pbitmap->bitmapinfoheader.planes = _planes;
pbitmap->bitmapinfoheader.bitsperpixel = _bitsperpixel;
pbitmap->bitmapinfoheader.compression = _compression;
pbitmap->bitmapinfoheader.imagesize = _pixelbytesize;
pbitmap->bitmapinfoheader.ypixelpermeter = _ypixelpermeter ;
pbitmap->bitmapinfoheader.xpixelpermeter = _xpixelpermeter ;
pbitmap->bitmapinfoheader.numcolorspallette = 0;
fwrite (pbitmap, 1, sizeof(bitmap),fp);
for(i=0;i<8192;i++)
{
pixelbuffer[i] = arr[i];
}
// memset(pixelbuffer,pixel,_pixelbytesize);
fwrite(pixelbuffer,1,_pixelbytesize,fp);
fclose(fp);
free(pbitmap);
free(pixelbuffer);
}
i am giving bits per pixel is 1 bit (i want either black or white), and not sure about other parameters which has to be change.
if i use _bitsperpixel as 24 then it is working properly but if i assign as 1 then getting it is getting crashed..
When _bitsperpixel == 1, then _pixelbytesize == 1024. Your loop runs till 8192, thus writing beyond the allocated memory.
Depending on what you store in your arr, you should either reduce the number of iterations of the loop to _pixelbytesize, or convert your bytes in arr into bits:
for(int i = 0; i < _pixelbytesize; ++i)
{
uint8_t b = 0;
for(int j = 0; j < 8; ++j)
b |= arr[8*i + j] >> 7 << j;
pixelbuffer[i] = b;
}
Note that this is a simple code that works only for image widths that are divisible by eight.
Using C and SDL2, I have a pixel array with an ARGB8888 format.
Uint32 *pixels = (Uint32 *) malloc (sizeof(Uint32)*(Uint32)windowWidth*(Uint32)windowHeight);
I want to put all that pixel information into a new SDL_Surface ready to save as a .bmp. How do I do this?
I'm unsure because new surfaces have RGBA8888 format and sdl convert functions require an existing surface to convert to a new surface. And there is no function which simply passes all pixel array values to a surface, so I know it will involve some sort of loop which assigns the pixels one by one.
You can manually save bitmap bits to a file. Bitmap files are usually 24bit or less, and bitmap viewers tend to ignore alpha. The code below assumes bits is 32-bit pixels. If you need 24-bit format, the input has to be converted from ARGB to RGB, and you must also account for padding.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#pragma pack(push, 1)
typedef struct my_BITMAPFILEHEADER {
uint16_t bfType;
uint32_t bfSize;
uint16_t bfReserved1;
uint16_t bfReserved2;
uint32_t bfOffBits;
}my_BITMAPFILEHEADER;
typedef struct my_BITMAPINFOHEADER {
uint32_t biSize;
int32_t biWidth;
int32_t biHeight;
uint16_t biPlanes;
uint16_t biBitCount;
uint32_t biCompression;
uint32_t biSizeImage;
int32_t biXPelsPerMeter;
int32_t biYPelsPerMeter;
uint32_t biClrUsed;
uint32_t biClrImportant;
}my_BITMAPINFOHEADER;
#pragma pack(pop)
int copy(uint8_t* bits, int width, int height, int bitcount)
{
//compiler test:
if(sizeof(my_BITMAPFILEHEADER) != 14 && sizeof(my_BITMAPINFOHEADER) != 40)
{
printf("bitmap structures not packed properly\n");
return 0;
}
//width_in_bytes is roughly w * bytes_per_pixel, it takes padding in to account
int width_in_bytes = ((width * bitcount + 31) / 32) * 4;
uint32_t imagesize = width_in_bytes * height;
my_BITMAPFILEHEADER filehdr = { 0 };
my_BITMAPINFOHEADER infohdr = { 0 };
memcpy(&filehdr, "BM", 2);
filehdr.bfSize = 54 + imagesize;
filehdr.bfOffBits = 54;
infohdr.biSize = 40;
infohdr.biPlanes = 1;
infohdr.biWidth = width;
infohdr.biHeight = height;
infohdr.biBitCount = bitcount;
infohdr.biSizeImage = imagesize;
FILE *fout = fopen("test.bmp", "wb");
fwrite(&filehdr, sizeof(filehdr), 1, fout);
fwrite(&infohdr, sizeof(infohdr), 1, fout);
fwrite((char*)bits, 1, imagesize, fout);
fclose(fout);
return 1;
}
Usage:
copy(bits, width, height, 32);
//or
copy(bits, width, height, 24);
I'm trying to change a pixel from a picture (format bmp, 24 bits).
I have this 3 structures:
for file header:
#pragma pack(2)
typedef struct {
unsigned short int typeID;
unsigned int size;
unsigned short int reserved1, reserved2;
unsigned int offset;
}BITMAPFILEHEADER;
#pragma pack(0)
for information header:
typedef struct {
unsigned int headerSize;
signed int widthPixel, heightPixel;
unsigned short int colorPlanes;
unsigned short int bitsPerPixel;
unsigned int compressionMethod;
unsigned int imagesize;
signed int xResolution, yResolution; // pixel per meter
unsigned int nbColor;
unsigned int importantColor;
}BITMAPINFOHEADER;
for RGB color:
typedef struct {
unsigned char blue;
unsigned char green;
unsigned char red;
unsigned char reserved;
} RGBCOLOR;
Then the main code:
int main(void) {
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;
FILE *inFileImage = NULL;
unsigned char *pBitsData = NULL;
int rowSize = 0;
int nImageSize = 0;
inFileImage = fopen("panda.bmp", "r+");
if (inFileImage == NULL)
{
fprintf(stderr, "Unable to open image");
return 0;
}
fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, inFileImage);
rewind(inFileImage);
pBitsData = (unsigned char *)calloc( fileHeader.size, sizeof(unsigned char) );
if( NULL == pBitsData )
{
printf("NO memory!!!!!\n");
}
else
{
fread(pBitsData, fileHeader.size * sizeof(unsigned char), 1, inFileImage);
memcpy(&fileHeader,pBitsData,sizeof(BITMAPFILEHEADER));
printf("Type ID: %x\n", fileHeader.typeID);
printf("File size: %d\n", fileHeader.size);
printf("Offset: %d\n", fileHeader.offset);
printf("**********************\n");
memcpy(&infoHeader, (pBitsData + sizeof(BITMAPFILEHEADER)), sizeof(BITMAPINFOHEADER));
printf("Header size: %u\n", infoHeader.headerSize);
printf("Width: %d\n", infoHeader.widthPixel);
printf("Height: %d\n", infoHeader.heightPixel);
printf("Nb planes: %d\n", infoHeader.colorPlanes);
printf("Bits per pixel: %d\n", infoHeader.bitsPerPixel);
printf("Compression method: %u\n", infoHeader.compressionMethod);
printf("Image size: %u\n", infoHeader.imagesize);
printf("Horizontal pixel per metre: %d\n", infoHeader.xResolution);
printf("Vertical pixel per metre: %d\n", infoHeader.yResolution);
printf("Number color in color table: %u\n", infoHeader.nbColor);
printf("Color important count: %u\n", infoHeader.importantColor);
printf("**********************\n");
rowSize = ((infoHeader.bitsPerPixel * infoHeader.widthPixel + 31) / 32) * 4;
printf("Row Size: %d\n", rowSize);
nImageSize = rowSize * abs(infoHeader.heightPixel);
printf("Pixel Array Size: %d\n", nImageSize);
printf("**********************\n");
RGBCOLOR* pixelData = (RGBCOLOR*)(pBitsData + fileHeader.offset);
// M is define with the value 5 - the 5 pixel from image
printf("Pixel %x, %x, %x\n", pixelData[M].blue, pixelData[M].green, pixelData[M].red);
//fseek(inFileImage, fileHeader.offset, SEEK_CUR);
//fread(pixelData, sizeof(RGBCOLOR), 1, inFileImage);
pixelData[M].red = 0x00;
pixelData[M].blue = 0xef;
pixelData[M].green = 0x00;
//memcpy((pBitsData + fileHeader.offset), &pixelData, sizeof(RGBCOLOR)); // <= here seems to be my problem
//fwrite(pixelData, sizeof(RGBCOLOR), 1, inFileImage); // how can i copy to image from a memory
printf("Pixel %x, %x, %x\n", pixelData[M].blue, pixelData[M].green, pixelData[M].red);
}
fclose(inFileImage);
if(NULL != pBitsData)
{
free(pBitsData);
}
return 0;
}
I want to change the 5th pixel from image (one of this: blue->red, green->blue, etc).
Can you show me where do i have mistakes in my code? And how can i change to work correctly my code? Thx
Edit:
instead of
RGBCOLOR* pixelData = (RGBCOLOR*)(pBitsData + fileHeader.offset);
// M is define with the value 5 - the 5 pixel from image
printf("Pixel %x, %x, %x\n", pixelData[M].blue, pixelData[M].green, pixelData[M].red);
//fseek(inFileImage, fileHeader.offset, SEEK_CUR);
//fread(pixelData, sizeof(RGBCOLOR), 1, inFileImage);
pixelData[M].red = 0x00;
pixelData[M].blue = 0xef;
pixelData[M].green = 0x00;
//memcpy((pBitsData + fileHeader.offset), &pixelData, sizeof(RGBCOLOR)); // <= here seems to be my problem
//fwrite(pixelData, sizeof(RGBCOLOR), 1, inFileImage); // how can i copy to image from a memory
printf("Pixel %x, %x, %x\n", pixelData[M].blue, pixelData[M].green, pixelData[M].red);
if i write
RGBCOLOR img;
fseek(inFileImage, fileHeader.offset, SEEK_SET);
img.blue = 0x00;
img.green = 0x00;
img.red = 0xff;
fwrite(&img, sizeof(RGBCOLOR), 1, inFileImage);
This will change the first pixel. But i want to copy in memory, and from there to change the pixel.
I use MinGW, so you'll need to change the #pragmas used for structure alignment.
Here's an all-in-one source that will
read an image
change a specified pixel
output the modified image to a new file
I haven't bothered with any error checking in the interests of brevity. I've tested it with a 24/32 bit images. It doesn't output a valid image when used with 32 bit images.
First, here's the before and after images. The image itself is 2x2 pixels, I've just shown it larger here for the sake of visibility.
Before:
After:
If you have a close look, you can see that the only byte different between the 2 images is the one at 0x3E in the file. We've changed a red pixel (00 00 FF) to a purple one (FF 00 FF). Since the image is a bottom-up one, the first 3 bytes of the pixel data are for the yellow pixel, the next 3 are for the blue one, 2 bytes of padding follows, then we have 3 for red, 3 for green and another 2 padding bytes.
Here's the code that made the change:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef WORD
#define WORD unsigned short
#endif
#ifndef DWORD
#define DWORD unsigned long
#endif
#ifndef BYTE
#define BYTE unsigned char
#endif
#ifndef LONG
#define LONG long
#endif
#define minGW 1
#ifdef minGW
#pragma pack(push,2)
#endif
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER,*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER;
#ifdef minGW
#pragma pack(pop)
#endif
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER,*LPBITMAPINFOHEADER,*PBITMAPINFOHEADER;
typedef struct tagRGBQUAD
{
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD,*LPRGBQUAD;
typedef struct tagBITMAPINFO
{
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO,*LPBITMAPINFO,*PBITMAPINFO;
typedef struct tagBITMAP
{
BITMAPINFOHEADER bmInfo;
unsigned char *pBits;
} BITMAP, *PBITMAP;
PBITMAP readBitmapFile(const char *filename)
{
FILE *fp;
PBITMAP result;
BITMAPFILEHEADER fileHeader;
BITMAPINFO bmpInfo;
fp = fopen(filename, "rb");
fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
fread(&bmpInfo, sizeof(BITMAPINFO), 1, fp);
fseek(fp, fileHeader.bfOffBits, SEEK_SET);
unsigned char *pBits = (unsigned char *)calloc(bmpInfo.bmiHeader.biSizeImage, sizeof(unsigned char) );
fread(pBits, sizeof(char), bmpInfo.bmiHeader.biSizeImage, fp);
fclose(fp);
result = (PBITMAP) calloc(1, sizeof(*result) );
memcpy(&result->bmInfo, &bmpInfo, sizeof(bmpInfo) );
result->pBits = pBits;
return result;
}
void saveBitmapFile(const char *filename, PBITMAP img)
{
FILE *fp;
BITMAPFILEHEADER fileHeader;
memset(&fileHeader, 0, sizeof(fileHeader));
fileHeader.bfType = 0x4d42; //'BM'
fileHeader.bfOffBits = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER);
fileHeader.bfSize = fileHeader.bfOffBits + (img->bmInfo.biSizeImage);
fp = fopen(filename, "wb");
fwrite(&fileHeader, sizeof(fileHeader), 1, fp);
fwrite(&img->bmInfo, sizeof(img->bmInfo), 1, fp);
fwrite(img->pBits, 1, img->bmInfo.biSizeImage, fp);
fclose(fp);
}
void myPixel(int x, int y, char r, char g, char b, PBITMAP image)
{
unsigned char *ptrToPixel;
int rowSize = ((image->bmInfo.biBitCount * image->bmInfo.biWidth + 31) / 32) * 4;
int curRow, bytesPerPixel;
if (image->bmInfo.biHeight < 0)
{
curRow = y;
}
else if (image->bmInfo.biHeight > 0)
{
curRow = (image->bmInfo.biHeight-1) - y;
}
bytesPerPixel = image->bmInfo.biBitCount / 8;
ptrToPixel = (curRow * rowSize) + (x*bytesPerPixel) + image->pBits;
ptrToPixel[0] = b;
ptrToPixel[1] = g;
ptrToPixel[2] = r;
}
int main()
{
PBITMAP inImage = readBitmapFile("colorTile.bmp");
myPixel(0,0, 255,0,255, inImage);
saveBitmapFile("colorTileOut.bmp", inImage);
}
EDIT:
After reading Can someone provide me a specification of 32 bit BMP image format? and https://forums.adobe.com/message/3272950#3272950 it seemed apparent that 32 bit bitmaps were using a V3 header - a header that includes 4 longs to specify the bitmask of each of the 4 channels. I've subsequently modified both the saveBitmapFile and myPixel routines and can confirm that the code now appears to function correctly with 32 bit bitmaps too.
void saveBitmapFile(const char *filename, PBITMAP img)
{
FILE *fp;
BITMAPFILEHEADER fileHeader;
unsigned long maskArray[] = {0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF};
memset(&fileHeader, 0, sizeof(fileHeader));
fileHeader.bfType = 0x4d42; //'BM'
fileHeader.bfOffBits = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER);
if (img->bmInfo.biBitCount == 32)
fileHeader.bfOffBits += sizeof(maskArray);
fileHeader.bfSize = fileHeader.bfOffBits + (img->bmInfo.biSizeImage);
fp = fopen(filename, "wb");
fwrite(&fileHeader, sizeof(fileHeader), 1, fp);
fwrite(&img->bmInfo, sizeof(img->bmInfo), 1, fp);
if (img->bmInfo.biBitCount == 32)
fwrite(&maskArray, sizeof(long), 4, fp);
fwrite(img->pBits, 1, img->bmInfo.biSizeImage, fp);
fclose(fp);
}
void myPixel(int x, int y, char r, char g, char b, PBITMAP image)
{
unsigned char *ptrToPixel;
int rowSize = ((image->bmInfo.biBitCount * image->bmInfo.biWidth + 31) / 32) * 4;
int curRow, bytesPerPixel;
if (image->bmInfo.biHeight < 0)
{
curRow = y;
}
else if (image->bmInfo.biHeight > 0)
{
curRow = (image->bmInfo.biHeight-1) - y;
}
bytesPerPixel = image->bmInfo.biBitCount / 8;
ptrToPixel = (curRow * rowSize) + (x*bytesPerPixel) + image->pBits;
if (image->bmInfo.biBitCount == 24)
{
ptrToPixel[0] = b;
ptrToPixel[1] = g;
ptrToPixel[2] = r;
}
else if (image->bmInfo.biBitCount == 32)
{
// ptrToPixel[0] = a;
ptrToPixel[1] = b;
ptrToPixel[2] = g;
ptrToPixel[3] = r;
}
}