以下实现适用于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
posted on 2012-11-19 17:19
王海光 阅读(7073)
评论(2) 编辑 收藏 引用 所属分类:
MFC