MFC bmp图片添加文字

MFC bmp图片添加文字
以下实现适用于24位BMP图片:
  1  // 单击一个Button,保存位图
  2  void  CDlgDlg::OnButton1() 
  3  {
  4      //  TODO: Add your control notification handler code here    
  5      HDC hDC = ::GetDC(GetSafeHwnd());
  6      HDC hMemDC = CreateCompatibleDC(hDC);
  7      // 打开位图文件
  8      HBITMAP hBmp = OpenBmpFile(hDC, "Splash.bmp");
  9      SelectObject(hMemDC, hBmp);
 10      // 在位图上写字
 11      RECT rect = {50, 50, 200, 200};
 12      SetBkMode(hMemDC, TRANSPARENT);
 13      DrawText(hMemDC, "你好", -1, &rect, DT_VCENTER);
 14  
 15      // 保存位图到文件
 16      PBITMAPINFO pBmpInfo = CreateBitmapInfoStruct(GetSafeHwnd(), hBmp);
 17      CreateBMPFile(GetSafeHwnd(), "Test.bmp", pBmpInfo, hBmp, hDC);
 18  
 19      DeleteDC(hMemDC);
 20      DeleteObject(hBmp); 
 21  }
 22  
 23  // 打开位图文件,得到位图句柄
 24  HBITMAP CDlgDlg::OpenBmpFile(HDC hDC, LPSTR lpszFileName)
 25  {
 26      HBITMAP hBmp = NULL;
 27      // 读位图文件,得到位图句柄
 28      HANDLE hFile = CreateFile(
 29          lpszFileName,
 30          GENERIC_READ,
 31          FILE_SHARE_READ,
 32          NULL,
 33          OPEN_EXISTING,
 34          FILE_ATTRIBUTE_NORMAL,
 35          NULL);
 36      if (hFile == INVALID_HANDLE_VALUE)
 37          return  NULL;
 38      // 读位图文件头
 39      BITMAPFILEHEADER bmpFileHeader;
 40      DWORD dwNumberOfBytesRead;
 41      if (ReadFile(hFile, (LPVOID)&bmpFileHeader,  sizeof (BITMAPFILEHEADER), &dwNumberOfBytesRead, NULL) == 0)
 42      {   
 43          CloseHandle(hFile);
 44          return  NULL;
 45      }
 46      // 读位图信息
 47      BITMAPINFO *pBmpInfo =  new  BITMAPINFO;
 48      if (ReadFile(hFile, pBmpInfo,  sizeof (BITMAPINFOHEADER), &dwNumberOfBytesRead, NULL) == 0)
 49      {   
 50          CloseHandle(hFile);
 51          return  NULL;
 52      }
 53      // 读位图数据
 54      LPVOID pBmpData;
 55      // 创建DIB位图句柄
 56      hBmp = CreateDIBSection(hDC, pBmpInfo, DIB_PAL_COLORS, &pBmpData, NULL, 0);
 57      if (hBmp == NULL)
 58      {
 59          DWORD dwErr = GetLastError();
 60          return  NULL;
 61      }
 62      else   // 读位图数据
 63           if (ReadFile(hFile, pBmpData, pBmpInfo->bmiHeader.biSizeImage, &dwNumberOfBytesRead, NULL) == 0)
 64          {   
 65              CloseHandle(hFile);
 66              return  NULL;
 67          }       
 68      CloseHandle(hFile); 
 69      return  hBmp;
 70  }
 71  
 72  // 下面的代码是把一张位图保存于文件中,参考MSDN
 73  PBITMAPINFO CreateBitmapInfoStruct(HWND hwnd, HBITMAP hBmp)
 74  { 
 75      BITMAP bmp; 
 76      PBITMAPINFO pbmi; 
 77      WORD    cClrBits; 
 78  
 79      //  Retrieve the bitmap's color format, width, and height. 
 80       if  (!GetObject(hBmp,  sizeof (BITMAP), (LPSTR)&bmp)) 
 81          return  NULL;
 82  
 83      //  Convert the color format to a count of bits. 
 84      cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel); 
 85      if  (cClrBits == 1) 
 86          cClrBits = 1; 
 87      else  if  (cClrBits <= 4) 
 88          cClrBits = 4; 
 89      else  if  (cClrBits <= 8) 
 90          cClrBits = 8; 
 91      else  if  (cClrBits <= 16) 
 92          cClrBits = 16; 
 93      else  if  (cClrBits <= 24) 
 94          cClrBits = 24; 
 95      else  cClrBits = 32; 
 96  
 97      //  Allocate memory for the BITMAPINFO structure. (This structure 
 98       //  contains a BITMAPINFOHEADER structure and an array of RGBQUAD 
 99       //  data structures.) 
100   
101       if  (cClrBits != 24) 
102           pbmi = (PBITMAPINFO) LocalAlloc(LPTR, 
103                      sizeof (BITMAPINFOHEADER) + 
104                      sizeof (RGBQUAD) * (1<< cClrBits)); 
105  
106       //  There is no RGBQUAD array for the 24-bit-per-pixel format. 
107   
108       else 
109           pbmi = (PBITMAPINFO) LocalAlloc(LPTR, 
110                      sizeof (BITMAPINFOHEADER)); 
111  
112      //  Initialize the fields in the BITMAPINFO structure. 
113   
114      pbmi->bmiHeader.biSize =  sizeof (BITMAPINFOHEADER); 
115      pbmi->bmiHeader.biWidth = bmp.bmWidth; 
116      pbmi->bmiHeader.biHeight = bmp.bmHeight; 
117      pbmi->bmiHeader.biPlanes = bmp.bmPlanes; 
118      pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel; 
119      if  (cClrBits < 24) 
120          pbmi->bmiHeader.biClrUsed = (1<<cClrBits); 
121  
122      //  If the bitmap is not compressed, set the BI_RGB flag. 
123      pbmi->bmiHeader.biCompression = BI_RGB; 
124  
125      //  Compute the number of bytes in the array of color 
126       //  indices and store the result in biSizeImage. 
127       //  For Windows NT/2000, the width must be DWORD aligned unless 
128       //  the bitmap is RLE compressed. This example shows this. 
129       //  For Windows 95/98, the width must be WORD aligned unless the 
130       //  bitmap is RLE compressed.
131      pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8
132                                    * pbmi->bmiHeader.biHeight; 
133      //  Set biClrImportant to 0, indicating that all of the 
134       //  device colors are important. 
135       pbmi->bmiHeader.biClrImportant = 0; 
136       return  pbmi; 
137   } 
138  
139  void  CreateBMPFile(HWND hwnd, LPTSTR pszFile, PBITMAPINFO pbi, 
140                    HBITMAP hBMP, HDC hDC) 
141   { 
142       HANDLE hf;                  //  file handle 
143      BITMAPFILEHEADER hdr;        //  bitmap file-header 
144      PBITMAPINFOHEADER pbih;      //  bitmap info-header 
145      LPBYTE lpBits;               //  memory pointer 
146      DWORD dwTotal;               //  total count of bytes 
147      DWORD cb;                    //  incremental count of bytes 
148      BYTE *hp;                    //  byte pointer 
149      DWORD dwTmp; 
150  
151      pbih = (PBITMAPINFOHEADER) pbi; 
152      lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
153  
154      if  (!lpBits) 
155           return  ;
156  
157      //  Retrieve the color table (RGBQUAD array) and the bits 
158       //  (array of palette indices) from the DIB. 
159       if  (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi, 
160          DIB_RGB_COLORS)) 
161      {
162          return  ;
163      }
164  
165      //  Create the .BMP file. 
166      hf = CreateFile(pszFile, 
167                     GENERIC_READ | GENERIC_WRITE, 
168                     (DWORD) 0, 
169                      NULL, 
170                     CREATE_ALWAYS, 
171                     FILE_ATTRIBUTE_NORMAL, 
172                     (HANDLE) NULL); 
173      if  (hf == INVALID_HANDLE_VALUE) 
174          return  ;
175      hdr.bfType = 0x4d42;         //  0x42 = "B" 0x4d = "M" 
176       //  Compute the size of the entire file. 
177      hdr.bfSize = (DWORD) ( sizeof (BITMAPFILEHEADER) + 
178                   pbih->biSize + pbih->biClrUsed 
179                   *  sizeof (RGBQUAD) + pbih->biSizeImage); 
180      hdr.bfReserved1 = 0; 
181      hdr.bfReserved2 = 0; 
182  
183      //  Compute the offset to the array of color indices. 
184      hdr.bfOffBits = (DWORD)  sizeof (BITMAPFILEHEADER) + 
185                      pbih->biSize + pbih->biClrUsed 
186                      *  sizeof  (RGBQUAD); 
187  
188      //  Copy the BITMAPFILEHEADER into the .BMP file. 
189       if  (!WriteFile(hf, (LPVOID) &hdr,  sizeof (BITMAPFILEHEADER), 
190          (LPDWORD) &dwTmp,  NULL)) 
191      {
192         return  ;
193      }
194  
195      //  Copy the BITMAPINFOHEADER and RGBQUAD array into the file. 
196       if  (!WriteFile(hf, (LPVOID) pbih,  sizeof (BITMAPINFOHEADER) 
197                    + pbih->biClrUsed *  sizeof  (RGBQUAD), 
198                    (LPDWORD) &dwTmp, ( NULL)))
199          return  ;
200  
201      //  Copy the array of color indices into the .BMP file. 
202      dwTotal = cb = pbih->biSizeImage; 
203      hp = lpBits; 
204      if  (!WriteFile(hf, (LPSTR) hp, ( int ) cb, (LPDWORD) &dwTmp,NULL)) 
205             return  ;
206  
207      //  Close the .BMP file. 
208        if  (!CloseHandle(hf)) 
209             return  ; 
210  
211      //  Free memory. 
212      GlobalFree((HGLOBAL)lpBits);
213  }

另一种实现:
 1  FILE *fp=fopen("back.bmp", "rb");
 2  if (fp == 0)
 3      return  1;
 4  
 5  fseek(fp,  sizeof (BITMAPFILEHEADER), 0);
 6  BITMAPINFOHEADER head;
 7  fread(&head,  sizeof (BITMAPINFOHEADER), 1, fp);
 8  int  bmpHeight = head.biHeight;
 9  int  bmpWidth = head.biWidth;
10  int  biBitCount = head.biBitCount;
11  int  lineByte = (bmpWidth*biBitCount/8+3)/4*4;
12  RGBQUAD *pColorTable;
13  if (biBitCount == 8)
14  {
15      pColorTable =  new  RGBQUAD[256];
16      fread(pColorTable,  sizeof (RGBQUAD), 256, fp);
17  }
18  unsigned  char  *pBmpBuf =  new  unsigned  char [lineByte*bmpHeight];
19  fread(pBmpBuf, 1, lineByte*bmpHeight, fp);
20  
21  CDC *m_pMemDC;
22  m_pMemDC =  new  CDC();
23  CDC *pDC;
24  pDC = GetDC();
25  m_pMemDC->CreateCompatibleDC(pDC);
26  CBitmap *m_pOldBmp = NULL;
27  CBitmap *m_pMemBmp =  new  CBitmap();        // 根据图片的大小创建一个兼容位图
28  m_pMemBmp->CreateCompatibleBitmap(pDC, bmpWidth, bmpHeight);
29  m_pOldBmp = m_pMemDC->SelectObject(m_pMemBmp);
30  
31  //  把图像的数据绘制到兼容位图上
32   
33  SetDIBits(m_pMemDC->GetSafeHdc(), (HBITMAP)m_pMemBmp->m_hObject, 
34      0, bmpHeight, (LPVOID)pBmpBuf, (BITMAPINFO*)&head, DIB_RGB_COLORS);
35  m_pMemDC->SetBkMode(TRANSPARENT);
36  m_pMemDC->SetTextColor(RGB(255, 0, 0));
37 
38  // 设置字体
39  CFont font;
40  font.CreateFont(10,10,0,0,10,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_DEFAULT_PRECIS,OUT_DEFAULT_PRECIS,DEFAULT_QUALITY,FF_SWISS,"宋体");
41  SelectObject(hMemDC, font); 
42  //  添加文字到指定位置
43  m_pMemDC->TextOut(17, 10, "hello");
44  
45  unsigned  char  *pTemp =  new  unsigned  char [lineByte*bmpHeight];
46  GetDIBits(m_pMemDC->GetSafeHdc(), (HBITMAP)m_pMemBmp->m_hObject, 0, bmpHeight, 
47      (LPVOID)pTemp, (BITMAPINFO*)&head, DIB_RGB_COLORS);
48  fclose(fp);
49  
50  char  bmpwrite[] = "c:\\2.bmp";
51  fp = fopen(bmpwrite,"wb");
52  BITMAPFILEHEADER fileHead;
53  fileHead.bfType = 0x4D42;
54  fileHead.bfSize =  sizeof (BITMAPFILEHEADER)+ sizeof (BITMAPINFOHEADER)+lineByte*bmpHeight;
55  fileHead.bfReserved1 = 0;
56  fileHead.bfReserved2 = 0;
57  fileHead.bfOffBits = 54;
58  fwrite(&fileHead,  sizeof (BITMAPFILEHEADER), 1, fp);
59  
60  fwrite(&head,  sizeof (BITMAPINFOHEADER), 1, fp);
61  fwrite(pTemp, lineByte*bmpHeight, 1, fp);
62  fclose(fp);
63  
64  delete m_pMemBmp;
65  delete m_pMemDC;
66  delete[] pBmpBuf;
67  delete[] pTemp;

本文相关链接:http://bbs.csdn.net/topics/260003736
                        http://bbs.csdn.net/topics/350077364

你可能感兴趣的:(MFC bmp图片添加文字)