Using GDI + to save a grayscale image of 8bpp, GDI + is really special .....
// Greyscale conversion#define GREY(r, g, b) (BYTE)(((WORD)r * 77 + (WORD)g * 150 + (WORD)b * 29) >> 8)// .299R + .587G + .114B//#define GREY(r, g, b) (BYTE)(((WORD)r * 169 + (WORD)g * 256 + (WORD)b * 87) >> 9)// .33R + 0.5G + .17B
// Bool gdiplusimage: savetofilewith8pp (tchar * pszpath) // function: save an 8-bit grayscale image // parameter: name of the pszpath file bool gdiplusimage to be saved :: savetofilewith8pp (tchar * pszpath) {bitmap * IMA = This-> m_pbitmap; // bitmap object of gdiplusimage if (! Ima |! Pszpath |! * Pszpath) {return false;} int width = m_pbitmap-> getwidth (); int Height = m_pbitmap-> getheight (); int bitcount = 8; // 1, 4, 8, 24, 32 /////////////////////////////////////// /// // build bitmap headerbitmapfileheader bitmapfileheader; bitmapinfoheader; byte rgbquad [4]; // rgbquadint Index = 0; DWORD stride = (bitcount * width + 31)/32) * 4; // each row is a multiple of 4, or a multiple of DWORD size switch (bitcount) {Case 1: Index = 2; bitmapfileheader. bfoffbits = (DWORD) (sizeof (bitmapfileheader) + sizeof (bitmapinfoheader) + 2*4); break; Case 4: Index = 16; bitmapfileheader. bfoffbits = (DWORD) (sizeof (bitmapfileheader) + sizeof (bitmapinfoheader) + 16*4); break; case 8: Index = 256; bitmapfileheader. bfoffbits = (DWORD) (sizeof (bitmapfileheader) + sizeof (bitmapinfoheader) + 256 * sizeof (rgbquad); break; Case 24: Case 32: Index = 0; bitmapfileheader. bfoffbits = (DWORD) (sizeof (bitmapfileheader) + sizeof (bitmapinfoheader); break; default: break;} // construct bitmap file header bitmapfileheader. bftype = 0x4d42; // a very important flag. bm identifies bitmapfileheader. bfsize = (DWORD) (bitmapfileheader. bfoffbits + height * STRIDE); // BMP file length: bitmapfileheader. bfreserved1 = 0; bitmapfileheader. bfreserved2 = 0; // construct the bitmap file information header bitmapinfoheader. bisize = sizeof (bitmapinfoheader); bitmapinfoheader. biwidth = width; bitmapinfoheader. biheight = height; bitmapinfoheader. biplanes = 1; bitmapinfoheader. bibitcount = bitcount; bitmapinfoheader. bicompression = bi_rgb; // The bitmapinfoheader is not compressed. bisizeimage = height * stride; bitmapinfoheader. bixpelspermeter = 3780; bitmapinfoheader. biypelspermeter = 3780; bitmapinfoheader. biclrused = 0; bitmapinfoheader. biclrimportant = 0; // create a BMP memory image and write the byte * pmybmp = new byte [bitmapfileheader. bfsize]; // my bitmap pmybmp byte * curr = pmybmp; // The curr pointer indicates the position of pmybmp memset (curr, 0, bitmapfileheader. bfsize); // write header information memcpy (curr, & bitmapfileheader, sizeof (bitmapfileheader); curr = pmybmp + sizeof (bitmapfileheader); memcpy (curr, & bitmapinfoheader, sizeof (bitmapinfoheader); curr + = sizeof (bitmapinfoheader); // construct the color palette if (8 = bitcount) {rgbquad [3] = 0; // rgbreservedfor (INT I = 0; I <256; I ++) {rgbquad [0] = rgbquad [1] = rgbquad [2] = I; memcpy (curr, rgbquad, sizeof (rgbquad); curr + = sizeof (rgbquad) ;}} else if (4 = bitcount) {rgbquad [3] = 0; for (INT I = 0; I <16; I ++) {rgbquad [0] = rgbquad [1] = rgbquad [2] = I; memcpy (curr, rgbquad, sizeof (rgbquad); curr + = sizeof (rgbquad);} else if (1 = bitcount) {rgbquad [3] = 0; // rgbreservedfor (INT I = 0; I <2; I ++) {rgbquad [0] = rgbquad [1] = rgbquad [2] = (256-I) % 256; memcpy (curr, rgbquad, sizeof (rgbquad); curr + = sizeof (rgbquad);} // you can use GDI + to load data sources or use other methods, write File data rect (, width, height); // gdiplus + bitmapdata bmdata; Status isucess = ima-> lockbits (& rect, imagelockmoderead, IMA-> getpixelformat (), & bmdata); byte * _ pixels = (byte *) bmdata. scan0; // start pointer of the memory position in the original rect area. byte is used as the unit type byte * _ prow; int _ strideoff8 = stride-width; // The stridebyte _ gray of the previously calculated index image; // build pixles, and the origin of the image data of GDI + (Windows) is in the lower left corner, refer to the iplimage structure switch (IMA-> getpixelformat () of opencv {Case pixelformat24bpprgb: {int _ strideoff24 = stride-3 * width; // stride of the previously calculated index image // grayscale for (INT I = height-1; I> = 0; I --) {_ prow = _ pixels + I * bmdata. stride; // The current row for (Int J = width-1; j> = 0; j --) {byte * _ pixels_ B; // bbyte * _ pixels_g; // Gbyte * _ pixels_r; // r_pixels_ B = _ prow ++; // blue_pixels_g = _ prow ++; // green_pixels_r = _ prow ++; // red_grey = grey (* _ pixels_r, * _ pixels_g, * _ pixels_ B); * curr = _ gray; // calculate the gray value of this Pixel based on red, green, and blue. curr ++ ;} curr + = _ strideoff8 ;}} break; Case pixelformat32bppargb: {// grayscale for (INT I = height-1; I> = 0; I --) {_ prow = _ pixels + I * bmdata. stride; For (Int J = width-1; j> = 0; j --) {byte * _ pixels_ B; byte * _ pixels_g; byte * _ pixels_r; _ pixels_ B = _ prow ++; // blue_pixels_g = _ prow ++; // green_pixels_r = _ prow ++; // red_prow ++; _ gray = grey (* _ pixels_r, * _ pixels_g, * _ pixels_ B); * curr = _ gray; curr ++;} curr + = _ strideoff8 ;}} break; case pixelformat8bppindexed: // GDI + can only be saved as 24-bit real-color images {// you cannot directly copy them using memcpy. You need a horizontal image, memcpy (curr, _ pixels, height * STRIDE ); for (INT I = height-1; I> = 0; I --) {_ prow = _ pixels + I * bmdata. stride; // For (Int J = width-1; j> = 0; j --) // {// _ gray = * _ prow ++; // * curr = _ gray; // curr ++; //} memcpy (curr, _ prow, width); curr + = stride ;}} break; default: break;} // Save the image pmybmp to the file try {cfile F (pszpath, cfile: modecreate | cfile: modewrite); F. write (pmybmp, bitmapfileheader. bfsize); F. close ();} catch (cfileexception * E) {tchar szcause [255]; e-> geterrormessage (szcause, 255); cstring MSG; MSG. format (_ T ("file error: % s, m_cause: % d \ n"), szcause, e-> m_cause); trace1 ("% s", MSG ); afxmessagebox (MSG); e-> Delete ();} // clean: ima-> unlockbits (& bmdata); Delete [] pmybmp; return true ;}