使用GDI+保存图像为8bpp的灰度图像
生活随笔
收集整理的這篇文章主要介紹了
使用GDI+保存图像为8bpp的灰度图像
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
使用GDI+保存圖像為8bpp的灰度圖像,GDI+真的有些特殊。。。。。
// BOOL GDIPlusImage::SaveToFileWith8pp(TCHAR *pszPath) // 功能:保存圖片為8位的灰度圖像 // 參數(shù): pszPath要保存的文件名 BOOL GDIPlusImage::SaveToFileWith8pp(TCHAR *pszPath) {Bitmap *ima = this->m_pBitmap; // GDIPlusImage的Bitmap對(duì)象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 bitmapInfoHeader; BYTE rgbquad[4]; // RGBQUADint index = 0;DWORD stride = ((bitcount*width + 31)/32)*4; //每行都是4的倍數(shù),或者說(shuō)是DWORD大小的倍數(shù)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;} //構(gòu)造Bitmap文件頭BITMAPFILEHEADER bitmapFileHeader.bfType = 0x4d42; // 很重要的標(biāo)志位 BM 標(biāo)識(shí)bitmapFileHeader.bfSize = (DWORD)(bitmapFileHeader.bfOffBits + height * stride); //bmp文件長(zhǎng)度 bitmapFileHeader.bfReserved1 = 0; bitmapFileHeader.bfReserved2 = 0; //構(gòu)造Bitmap文件信息頭BITMAPINFOHEADER bitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER); bitmapInfoHeader.biWidth = width; bitmapInfoHeader.biHeight = height; bitmapInfoHeader.biPlanes = 1; bitmapInfoHeader.biBitCount = bitcount;bitmapInfoHeader.biCompression = BI_RGB; // 未壓縮bitmapInfoHeader.biSizeImage = height * stride; bitmapInfoHeader.biXPelsPerMeter = 3780; bitmapInfoHeader.biYPelsPerMeter = 3780; bitmapInfoHeader.biClrUsed = 0; bitmapInfoHeader.biClrImportant = 0; //創(chuàng)建BMP內(nèi)存映像,寫(xiě)入位圖頭部BYTE *pMyBmp = new BYTE[bitmapFileHeader.bfSize]; // 我的位圖pMyBmpBYTE *curr = pMyBmp; // curr指針指示pMyBmp的位置memset(curr, 0, bitmapFileHeader.bfSize); //寫(xiě)入頭信息 memcpy(curr, &bitmapFileHeader,sizeof(BITMAPFILEHEADER));curr = pMyBmp + sizeof(BITMAPFILEHEADER); memcpy(curr, &bitmapInfoHeader,sizeof(BITMAPINFOHEADER)); curr += sizeof(BITMAPINFOHEADER);//構(gòu)造調(diào)色板 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); } }//用GDI+加載數(shù)據(jù)源,也可以是其他的,寫(xiě)入文件數(shù)據(jù)Rect rect(0,0,width,height); // Gdiplus+BitmapData bmData;Status iSucess = ima->LockBits(&rect,ImageLockModeRead,ima->GetPixelFormat() ,&bmData);BYTE *_pixels = (BYTE*)bmData.Scan0; //原圖rect區(qū)域內(nèi)存位置的起始指針,以BYTE作為單元類型BYTE *_pRow;int _strideoff8 = stride - width; //前面計(jì)算的索引圖像的strideBYTE _grey;// build pixles, GDI+ (windows)的圖像數(shù)據(jù)的原點(diǎn)在左下角,參考一下OpenCV的IplImage結(jié)構(gòu)體switch(ima->GetPixelFormat()){case PixelFormat24bppRGB:{int _strideoff24 = stride - 3*width; //前面計(jì)算的索引圖像的stride// 灰度化for (int i=height-1; i >= 0; i--){_pRow = _pixels + i*bmData.Stride; // 當(dāng)前的行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 = _grey; //根據(jù)紅綠藍(lán)求出此像素的灰度值curr++;}curr += _strideoff8;}}break;case PixelFormat32bppARGB:{// 灰度化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++;_grey = GREY(*_pixels_r, *_pixels_g, *_pixels_b); *curr = _grey;curr++;}curr += _strideoff8;}}break;case PixelFormat8bppIndexed: // Gdi+只能保存成24位真彩色的圖像{// 不能直接用memcpy復(fù)制,需要水平鏡像,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--) // { // _grey = *_pRow++; // *curr = _grey; // curr++; // }memcpy(curr, _pRow, width);curr += stride;}}break;default:break;}// 保存圖像 pMyBmp 到文件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; }
總結(jié)
以上是生活随笔為你收集整理的使用GDI+保存图像为8bpp的灰度图像的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【原创】PageAdminCMS 前台S
- 下一篇: 垂直搜索引擎的性能优化@机票行业