16.4.1自定义的 DIBSTRUCT结构体

字段

含义

PBYTE *ppRow

指向位图视觉上最上面的一行像素。(不管是自下而上,还是自上而下)

②放在第一个字段,为的是后面定义宏时可方便访问到

int iSignature

=“Dib ”,是这个结构体的标志

HBITMAP hBitmap

存储了由CreateDIBSection返回的位图句柄(注意,实质是DIB,但兼有DDB的特点,可直接BitBlt)

BYTE *pBits

指向像素阵列的指针,其指针值在CreateDIBSection中设定,而所指向的内存由操作系统管理,删除位图句柄后会自动释放。

DIBSECTION

在DibCreateFromInfo中调用GetObject来填充该结构体,以方便使用(注意DibCreateFromInfo函数被本例所有创建DIB的函数所调用)

int iRShift[3]

是个数组,3个元素分别为R、G、B颜色遮罩需右移的位数

int iLShift[3]

是个数组,3个元素分别为R、G、B颜色遮罩需左移的位数

16.4.2 信息获取函数

(1)DibIsValid函数——用来确保DIBSTRUCT结构的有效性

(2)DibIsAddressable(也可定义为DibIsNotCompression):判断位图是否被压缩

(3)DibInfoHeaderSize等一组函数用于获取DIB区块各部分大小,这些函数可用来将一个DIB Section转换为紧凑DIB。

(4)获得各类指针的函数:如DibInfoHeaderPtr(获取BITMAPINFOHEADER指针)

16.4.3 读写像素信息

(1)DibPixelPtr:用来获取像素的内存指针。注意DIBSTRUCT结构的ppRow是一个指向从上向下排列的DIB像素行的指针,即ppRow[0]是位图视觉上的最上面的一行。如果位图被压缩时返回NULL。

(2)DibGetColor和DibSetColor:像素点在颜色表的值。对于1、4、8位,其RGB值就是要通过颜色表来查找。(对于16、24、32位的,不能通过这两个函数获取,其RGB值要通过掩码和位移获得)

16.4.4 创建和转换

(1)DibCreateFromInfo函数:是DIBHELP库中唯一一个调用CreateDIBSection并为DIBSTRUCT分配内存的函数。其他所有创建或复制都要通过调用该函数来完成

  ①参数:BITMAPINFO结构的指针

  ②该函数调用CreateDIBSeciton后会初始化DIBSTRUCT的所有字段,第一个字段ppRow总是指向DIB的最上面的一行。

(2)DibDelete用来删除由DibCreateFromInfo创建的位图,并释放内存。

(3)DibCopyToPackedDib和DibCopyFromPackedDib常用于应用程序与剪贴板交换DIB

(4)DibCopyToDdb:从一个DIB创建一个GDI位图对象。

16.4.5 宏——快速读写像素位的宏(在DIBHELP.H头文件中)

16.4.6 Dibble程序

(1)三个重要的静态变量hdib、hPalette、hBitmap

(2)WM_USER_SETSCROLL和WM_USER_CREATEPAL消息:用来重置滚动条和创建调色板

(3)DisplayDib:显示位图,提供正常、居中、满拉到客户区、各向同性等4种方式。

①WM_PAINT消息中:位图句柄来自于DibCopyToDdb函数。(因可能要用调色板来显示)

②打印时:从DitbitmapHandle得到DIB Section位图的句柄。

(4)剪贴板:调用DibCopyToPackedDib和DibCopyFromPackedDib函数

(5)Flip函数——上下翻转;Rotate——顺时针转90度。

  ①DibFlipHorizontal函数:演示通过DibGetPixel和DibSetPixel,效率较低

  ②DibRotateRight函数:通过DIBHELP.H中定义的宏来读写像素,效率高。

16.4.7 简单的调色板和优化的调色板——在256色的视频模式下,可选择不同调色板

(1)创建调色板的函数

  ①半色调调色板——系统API提供的。会使用万能调色板与抖动技术来实现该调色板。

  ②DibPalDibTable:根据DIB颜色表来创建调色板

  ③DibPalAllPurpose:创建通用的调色板,其颜色见DibPal.C文件

  ④DibPalUniformGrays:创建一个只有灰度色阶的调色板

(2)优化调色板

  ①均匀分布算法:DibPalUniformColors——创建iNumR×iNumG×iNumB调色板,一般8级红色、8级绿色和4级蓝色,因为人眼为蓝色比较不敏感。

  ②流行度算法——DibPalPopularity函数

  A、使用位图中被使用最多的256种RGB色值来构成调色板。但24位RGB,可表示2^24种颜色,如果每种颜色用1个int型保存使用次数的话,共需要64M左右,内存消耗大。

  B、解决办法是只用RGB权重最高的几位,如用6位而非8位表示R值(因为显示器的解析度也是6位)。这样只需1M,而5位时只需32768字节。

③中分算法——DibPalMedianCut(PaulHeckbert发明)

  A、中分算法中RGB值被映射到一个三维坐标中,三个坐标轴分别表示R、G、B

  B、每个像素点的RGB值都能在这个坐标系中找到相应的点

  C、找到一个能包含所有图像像素的长方体,取最长的一条边,将长方体分成两部分,使划分后的每个部分含有相同的像素数量。

  D、然后对这两个盒子做同样的划分,这样2个分为4个、4个分为8个,8个分为16个,然后是32个,64个、128个、256个。

  E、现在得到256个盒子,每个都包含了相等的像素数。对每个盒子的颜色取其平均值,并利用这个结构来改变调色板。

16.4.8 格式转换——参考DIbConv.c文件

(1)GetNearestPaletteIndex返回获得调色板中最接近的颜色的索引值

  UINT GetNearestPaletteIndex

  (

  HPALETTE hpal,     // 逻辑调色板

  COLORREF crColor   // 要匹配的颜色

  )

(2)DibPalVga:获取标准16色显示器颜色值

(3)HDIBDibConvert(HDIB hdibSrc, int iBitCountDst);用来进行格式转换的函数
【Dibble程序】
效果图

//Dibble.c主程序

  1. /*------------------------------------------------------------
  2. DIBBLE.C -- Bitmap and Palette Program
  3. (c) Charles Petzold, 1998
  4. ------------------------------------------------------------*/
  5. #include <windows.h>
  6. #include "resource.h"
  7. #include "DibHelp.h"
  8. #include "DibConv.h"
  9. #include "DibPal.h"
  10. #define WM_USER_SETSCROLLS (WM_USER + 1)
  11. #define WM_USER_DELETEDIB (WM_USER + 2)
  12. #define WM_USER_DELETEPAL (WM_USER + 3)
  13. #define WM_USER_CREATEPAL (WM_USER + 4)
  14. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  15. static TCHAR szAppName[] = TEXT("Dibble");
  16. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  17. PSTR szCmdLine, int iCmdShow)
  18. {
  19. HWND hwnd;
  20. MSG msg;
  21. WNDCLASSEX wndclass;
  22. HACCEL hAccel;
  23. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  24. wndclass.cbSize = sizeof(WNDCLASSEX);
  25. wndclass.lpfnWndProc = WndProc;
  26. wndclass.cbClsExtra = ;
  27. wndclass.cbWndExtra = ;
  28. wndclass.hInstance = hInstance;
  29. wndclass.hIcon = LoadIcon(hInstance, szAppName);
  30. wndclass.hIconSm = LoadIcon(hInstance, szAppName);
  31. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  32. wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  33. wndclass.lpszMenuName = szAppName;
  34. wndclass.lpszClassName = szAppName;
  35. if (!RegisterClassEx(&wndclass))
  36. {
  37. MessageBox(NULL, TEXT("This program requires Windows NT!"),
  38. szAppName, MB_ICONERROR);
  39. return ;
  40. }
  41.  
  42. hwnd = CreateWindow(szAppName, // window class name
  43. szAppName, // window caption
  44. WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL, // window style
  45. CW_USEDEFAULT, // initial x position
  46. CW_USEDEFAULT, // initial y position
  47. CW_USEDEFAULT, // initial x size
  48. CW_USEDEFAULT, // initial y size
  49. NULL, // parent window handle
  50. NULL, // window menu handle
  51. hInstance, // program instance handle
  52. NULL); // creation parameters
  53.  
  54. ShowWindow(hwnd, iCmdShow);
  55. UpdateWindow(hwnd);
  56. hAccel = LoadAccelerators(hInstance, szAppName);
  57. while (GetMessage(&msg, NULL, , ))
  58. {
  59. if (!TranslateAccelerator(hwnd, hAccel, &msg))
  60. {
  61. TranslateMessage(&msg);
  62. DispatchMessage(&msg);
  63. }
  64. }
  65. return msg.wParam;
  66. }
  67. /*-------------------------------------------------------------------------------
  68. DisplayDib:根据菜单项的选择来显示(打印)DIB的实际大小图像或缩放的图像
  69. --------------------------------------------------------------------------------*/
  70. int DisplayDib(HDC hdc, HBITMAP hBitmap, int x, int y,
  71. int cxClient, int cyClient,
  72. WORD wShow, BOOL fHalftonePalette)
  73. {
  74. BITMAP bitmap;
  75. HDC hdcMem;
  76. int cxBitmap, cyBitmap, iReturn;
  77. GetObject(hBitmap, sizeof(BITMAP), &bitmap);
  78. cxBitmap = bitmap.bmWidth;
  79. cyBitmap = bitmap.bmHeight;
  80. SaveDC(hdc);
  81. if (fHalftonePalette)
  82. SetStretchBltMode(hdc, HALFTONE);
  83. else
  84. SetStretchBltMode(hdc, COLORONCOLOR);
  85. hdcMem = CreateCompatibleDC(hdc);
  86. SelectObject(hdcMem, hBitmap);
  87. switch (wShow)
  88. {
  89. case IDM_SHOW_NORMAL:
  90. if (fHalftonePalette)
  91. {
  92. iReturn = StretchBlt(hdc, , ,
  93. min(cxClient, cxBitmap - x),
  94. min(cyClient, cyBitmap - y),
  95. hdcMem, x, y,
  96. min(cxClient, cxBitmap - x),
  97. min(cyClient, cyBitmap - y),
  98. SRCCOPY);
  99. } else
  100. {
  101. iReturn = BitBlt(hdc, , ,
  102. min(cxClient, cxBitmap - x),
  103. min(cyClient, cyBitmap - y),
  104. hdcMem, x, y, SRCCOPY);
  105. }
  106. break;
  107. case IDM_SHOW_CENTER:
  108. if (fHalftonePalette)
  109. {
  110. iReturn = StretchBlt(hdc, (cxClient - cxBitmap) / , (cyClient - cyBitmap) / ,
  111. cxBitmap, cyBitmap,
  112. hdcMem, , ,
  113. cxBitmap, cyBitmap,
  114. SRCCOPY);
  115. } else
  116. {
  117. iReturn = BitBlt(hdc, (cxClient - cxBitmap) / , (cyClient - cyBitmap) / ,
  118. cxBitmap, cyBitmap,
  119. hdcMem, , , SRCCOPY);
  120. }
  121. break;
  122. case IDM_SHOW_STRETCH:
  123. iReturn = StretchBlt(hdc, , ,
  124. cxClient, cyClient,
  125. hdcMem, , ,
  126. cxBitmap, cyBitmap,
  127. SRCCOPY);
  128. break;
  129. case IDM_SHOW_ISOSTRETCH:
  130. SetMapMode(hdc, MM_ISOTROPIC);
  131. SetWindowExtEx(hdc, cxBitmap, cyBitmap, NULL);
  132. SetViewportExtEx(hdc, cxClient, cyClient, NULL);
  133. SetWindowOrgEx(hdc, cxBitmap / , cyBitmap / , NULL);
  134. SetViewportOrgEx(hdc, cxClient / , cyClient / , NULL);
  135. //iReturn = StretchBlt(hdc, 0, 0,
  136. // cxBitmap, cyBitmap,
  137. // hdcMem, 0, 0,
  138. // cxBitmap, cyBitmap,
  139. // SRCCOPY);
  140. iReturn = BitBlt(hdc, , ,
  141. cxBitmap, cyBitmap,
  142. hdcMem, , ,
  143. SRCCOPY);
  144. break;
  145. }
  146. DeleteDC(hdcMem);
  147. RestoreDC(hdc, -);
  148. return iReturn;
  149. }
  150. /*-------------------------------------------------------------------------------
  151. PaletteMenu:设置“Palette”各菜单项的Check属性
  152. --------------------------------------------------------------------------------*/
  153. void PaletteMenu(HMENU hMenu, WORD wItemNew)
  154. {
  155. static WORD wItem = IDM_PAL_NONE;
  156. CheckMenuItem(hMenu, wItem, MF_UNCHECKED);
  157. wItem = wItemNew;
  158. CheckMenuItem(hMenu, wItem, MF_CHECKED);
  159. }
  160. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  161. {
  162. static OPENFILENAME ofn;
  163. static TCHAR szFileName[MAX_PATH], szTitleName[MAX_PATH];
  164. static TCHAR szFilter[] = TEXT("Bitmap Files (*.BMP)\0*.bmp\0")
  165. TEXT("All Files (*.*)\0*.*\0\0");
  166. static TCHAR* szCompression[] = {
  167. TEXT("BI_RGB"), TEXT("BI_RLE8"),
  168. TEXT("BI_RLE4"), TEXT("BI_BITFIELDS"),
  169. TEXT("Unknown") };
  170. static HDIB hdib;
  171. static HPALETTE hPalette;
  172. static HBITMAP hBitmap;
  173. static BOOL fHalftonePalette;
  174. static HMENU hMenu;
  175. BOOL fSuccess;
  176. static int cxClient, cyClient, iHscroll, iVscroll;
  177. static WORD wShow = IDM_SHOW_NORMAL;
  178.  
  179. static PRINTDLG printdlg = { sizeof(PRINTDLG) };
  180. static DOCINFO di = { sizeof(DOCINFO), TEXT("Dibble:Printing") };
  181. int cxPage, cyPage;
  182. HDC hdc, hdcPrn;
  183. HGLOBAL hGlobal;
  184. BYTE* pGlobal;
  185. HDIB hdibNew;
  186. PAINTSTRUCT ps;
  187. SCROLLINFO si;
  188. int iEnable, iConvert = ;
  189. TCHAR szBuffer[];
  190. switch (message)
  191. {
  192. case WM_CREATE:
  193. //将菜单句柄保存在静态变量hMenu中
  194. hMenu = GetMenu(hwnd);
  195. //初始化打开文件对话框
  196. memset(&ofn, , sizeof(OPENFILENAME));
  197. ofn.lStructSize = sizeof(OPENFILENAME);
  198. ofn.hwndOwner = hwnd;
  199. ofn.lpstrFilter = szFilter;
  200. ofn.lpstrFile = szFileName;
  201. ofn.nMaxFile = MAX_PATH;
  202. ofn.lpstrFileTitle = szTitleName;
  203. ofn.nMaxFileTitle = MAX_PATH;
  204. ofn.Flags = OFN_OVERWRITEPROMPT;
  205. ofn.lpstrDefExt = TEXT("bmp");
  206. return ;
  207. case WM_SIZE:
  208. cxClient = LOWORD(lParam);
  209. cyClient = HIWORD(lParam);
  210.  
  211. wParam = FALSE; //贯穿功能,继续执行下面的代码
  212.  
  213. //用户自定义消息,设置滚动条,如果显示模式是正常模式,则隐藏滚动条。如果
  214. //wParam==TRUE,则复位滚动条的位置
  215. case WM_USER_SETSCROLLS:
  216. if (hdib == NULL || wShow != IDM_SHOW_NORMAL)
  217. {
  218. si.cbSize = sizeof(SCROLLINFO);
  219. si.fMask = SIF_RANGE;
  220. si.nMin = ;
  221. si.nMax = ;
  222. SetScrollInfo(hwnd, SB_VERT, &si, TRUE); //隐藏
  223. SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
  224. } else
  225. {
  226. //垂直滚动条
  227. si.cbSize = sizeof(SCROLLINFO);
  228. si.fMask = SIF_ALL;
  229. GetScrollInfo(hwnd, SB_VERT, &si);
  230. si.nMin = ;
  231. si.nMax = DibHeight(hdib);
  232. si.nPage = cyClient;
  233. if ((BOOL)wParam) //恢复到0的默认位置
  234. si.nPos = ;
  235. SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
  236. GetScrollInfo(hwnd, SB_VERT, &si);
  237. iVscroll = si.nPos;
  238. //水平滚动条
  239. GetScrollInfo(hwnd, SB_HORZ, &si);
  240. si.nMin = ;
  241. si.nMax = DibWidth(hdib);
  242. si.nPage = cxClient;
  243. if ((BOOL)wParam) //恢复到0的默认位置
  244. si.nPos = ;
  245. SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
  246. GetScrollInfo(hwnd, SB_HORZ, &si);
  247. iHscroll = si.nPos;
  248. }
  249. return ;
  250. case WM_VSCROLL:
  251. si.cbSize = sizeof(SCROLLINFO);
  252. si.fMask = SIF_ALL;
  253. GetScrollInfo(hwnd, SB_VERT, &si);
  254. iVscroll = si.nPos;
  255. switch (LOWORD(wParam))
  256. {
  257. case SB_LINEUP: si.nPos -= ; break;
  258. case SB_LINEDOWN: si.nPos += ; break;
  259. case SB_PAGEUP: si.nPage -= si.nPage; break;
  260. case SB_PAGEDOWN: si.nPage += si.nPage; break;
  261. case SB_THUMBTRACK: si.nPos = si.nTrackPos; break;
  262. default: break;
  263. }
  264. si.fMask = SIF_POS;
  265. SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
  266. GetScrollInfo(hwnd, SB_VERT, &si);
  267. if (si.nPos != iVscroll)
  268. {
  269. ScrollWindow(hwnd, , iVscroll - si.nPos, NULL, NULL);
  270. iVscroll = si.nPos;
  271. UpdateWindow(hwnd); //立即更新窗口,这行可以注释掉
  272. }
  273. return ;
  274. case WM_HSCROLL:
  275. si.cbSize = sizeof(SCROLLINFO);
  276. si.fMask = SIF_ALL;
  277. GetScrollInfo(hwnd, SB_HORZ, &si);
  278. iHscroll = si.nPos;
  279. switch (LOWORD(wParam))
  280. {
  281. case SB_LINELEFT: si.nPos -= ; break;
  282. case SB_LINERIGHT: si.nPos += ; break;
  283. case SB_PAGELEFT: si.nPage -= si.nPage; break;
  284. case SB_PAGERIGHT: si.nPage += si.nPage; break;
  285. case SB_THUMBTRACK: si.nPos = si.nTrackPos; break;
  286. default: break;
  287. }
  288. si.fMask = SIF_POS;
  289. SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
  290. GetScrollInfo(hwnd, SB_HORZ, &si);
  291. if (si.nPos != iHscroll)
  292. {
  293. ScrollWindow(hwnd, iHscroll - si.nPos, , NULL, NULL);
  294. iHscroll = si.nPos;
  295. UpdateWindow(hwnd); //立即更新窗口,这行可以注释掉
  296. }
  297. return ;
  298. case WM_INITMENUPOPUP:
  299. if (hdib)
  300. iEnable = MF_ENABLED;
  301. else
  302. iEnable = MF_GRAYED;
  303. EnableMenuItem(hMenu, IDM_FILE_SAVE, iEnable);
  304. EnableMenuItem(hMenu, IDM_FILE_PRINT, iEnable);
  305. EnableMenuItem(hMenu, IDM_FILE_PROPERTIES, iEnable);
  306. EnableMenuItem(hMenu, IDM_EDIT_CUT, iEnable);
  307. EnableMenuItem(hMenu, IDM_EDIT_COPY, iEnable);
  308. EnableMenuItem(hMenu, IDM_EDIT_DELETE, iEnable);
  309. if (DibIsAddressable(hdib))
  310. iEnable = MF_ENABLED;
  311. else
  312. iEnable = MF_GRAYED;
  313. EnableMenuItem(hMenu, IDM_EDIT_ROTATE, iEnable);
  314. EnableMenuItem(hMenu, IDM_EDIT_FLIP, iEnable);
  315. EnableMenuItem(hMenu, IDM_CONVERT_01, iEnable);
  316. EnableMenuItem(hMenu, IDM_CONVERT_04, iEnable);
  317. EnableMenuItem(hMenu, IDM_CONVERT_08, iEnable);
  318. EnableMenuItem(hMenu, IDM_CONVERT_16, iEnable);
  319. EnableMenuItem(hMenu, IDM_CONVERT_24, iEnable);
  320. EnableMenuItem(hMenu, IDM_CONVERT_32, iEnable);
  321. switch (DibBitCount(hdib))
  322. {
  323. case : EnableMenuItem(hMenu, IDM_CONVERT_01, MF_GRAYED); break;
  324. case : EnableMenuItem(hMenu, IDM_CONVERT_04, MF_GRAYED); break;
  325. case : EnableMenuItem(hMenu, IDM_CONVERT_08, MF_GRAYED); break;
  326. case : EnableMenuItem(hMenu, IDM_CONVERT_16, MF_GRAYED); break;
  327. case : EnableMenuItem(hMenu, IDM_CONVERT_24, MF_GRAYED); break;
  328. case : EnableMenuItem(hMenu, IDM_CONVERT_32, MF_GRAYED); break;
  329. }
  330. if (hdib && DibColorSize(hdib) > )
  331. iEnable = MF_ENABLED;
  332. else
  333. iEnable = MF_GRAYED;
  334. EnableMenuItem(hMenu, IDM_PAL_DIBTABLE, iEnable);
  335. if (DibIsAddressable(hdib) && DibBitCount(hdib)>)
  336. iEnable = MF_ENABLED;
  337. else
  338. iEnable = MF_GRAYED;
  339. EnableMenuItem(hMenu, IDM_PAL_OPT_POP4, iEnable);
  340. EnableMenuItem(hMenu, IDM_PAL_OPT_POP5, iEnable);
  341. EnableMenuItem(hMenu, IDM_PAL_OPT_POP6, iEnable);
  342. EnableMenuItem(hMenu, IDM_PAL_OPT_MEDCUT, iEnable);
  343. EnableMenuItem(hMenu, IDM_EDIT_PASTE, IsClipboardFormatAvailable(CF_DIB) ? MF_ENABLED : MF_GRAYED);
  344. return ;
  345. case WM_COMMAND:
  346. switch (LOWORD(wParam))
  347. {
  348. case IDM_FILE_OPEN:
  349. //显示“打开文件”对话框
  350. if (!GetOpenFileName(&ofn))
  351. return ;
  352. //如果DIB和调色板己经存在,则删除它们
  353. SendMessage(hwnd, WM_USER_DELETEDIB, , );
  354. //加载DIB文件到内存
  355. SetCursor(LoadCursor(NULL, IDC_WAIT));
  356. ShowCursor(TRUE);
  357. hdib = DibFileLoad(szFileName);
  358. SetCursor(LoadCursor(NULL, IDC_ARROW));
  359. ShowCursor(FALSE);
  360. //重置滚动条
  361. SendMessage(hwnd, WM_USER_SETSCROLLS, TRUE, );
  362. //创建调色板和DDB
  363. SendMessage(hwnd, WM_USER_CREATEPAL, TRUE, ); //根据调色板,创建DDB——hBitmap
  364.  
  365. if (!hdib)
  366. {
  367. MessageBox(hwnd, TEXT("Cannot load DIB file!"),
  368. szAppName, MB_OK | MB_ICONEXCLAMATION);
  369. }
  370. InvalidateRect(hwnd, NULL, TRUE);
  371. return ;
  372. case IDM_FILE_SAVE:
  373. //打开“保存”对话框
  374. if (!GetSaveFileName(&ofn))
  375. return ;
  376. //将DIB保存到文件中
  377. SetCursor(LoadCursor(NULL, IDC_WAIT));
  378. ShowCursor(TRUE);
  379. fSuccess = DibFileSave(hdib, szFileName);
  380. SetCursor(LoadCursor(NULL, IDC_ARROW));
  381. ShowCursor(FALSE);
  382. if (!fSuccess)
  383. {
  384. MessageBox(hwnd, TEXT("Cannot Save DIB file!"),
  385. szAppName, MB_OK | MB_ICONEXCLAMATION);
  386. }
  387. return ;
  388. case IDM_FILE_PRINT:
  389. if (!hdib)
  390. return ;
  391. //获得打印机DC
  392. printdlg.Flags = PD_RETURNDC | PD_NOPAGENUMS | PD_NOSELECTION;
  393. if (!PrintDlg(&printdlg))
  394. return ;
  395. if (NULL == (hdcPrn = printdlg.hDC))
  396. {
  397. MessageBox(hwnd, TEXT("Cannot obtain Printer DC"), szAppName, MB_ICONEXCLAMATION | MB_OK);
  398. return ;
  399. }
  400.  
  401. //检查打印机是否支持打印位图
  402. if (!(RC_BITBLT & GetDeviceCaps(hdcPrn, RASTERCAPS)))
  403. {
  404. DeleteDC(hdcPrn);
  405. MessageBox(hwnd, TEXT("Printer cannot print bitmaps"), szAppName, MB_ICONEXCLAMATION | MB_OK);
  406. return ;
  407. }
  408. //获取打机印的可打印区域
  409. cxPage = GetDeviceCaps(hdcPrn, HORZRES);
  410. cyPage = GetDeviceCaps(hdcPrn, VERTRES);
  411.  
  412. fSuccess = FALSE;
  413. //将DIB发送到打印机
  414. SetCursor(LoadCursor(NULL, IDC_WAIT));
  415. ShowCursor(TRUE);
  416. if ((StartDoc(hdcPrn, &di) > ) && (StartPage(hdcPrn) > ))
  417. {
  418. DisplayDib(hdcPrn, DibBitmapHandle(hdib), , , cxPage, cyPage, wShow, FALSE);
  419. if (EndPage(hdcPrn) > )
  420. {
  421. fSuccess = TRUE;
  422. EndDoc(hdcPrn);
  423. }
  424. }
  425. ShowCursor(FALSE);
  426. SetCursor(LoadCursor(NULL, IDC_ARROW));
  427. DeleteDC(hdcPrn);
  428. if (!fSuccess)
  429. MessageBox(hwnd, TEXT("Cannot print bitmaps"),
  430. szAppName, MB_ICONEXCLAMATION | MB_OK);
  431. return ;
  432. case IDM_FILE_PROPERTIES:
  433. if (!hdib)
  434. return ;
  435. wsprintf(szBuffer, TEXT("Pixel width:\t%i\n") //%i与%d一样的
  436. TEXT("Pixel Height:\t%i\n")
  437. TEXT("Bits per pixel:\t%i\n")
  438. TEXT("Number of colors:\t%i\n")
  439. TEXT("Compression:\t%s\n"),
  440. DibWidth(hdib), DibHeight(hdib),
  441. DibBitCount(hdib), DibNumColors(hdib),
  442. szCompression[min(, DibCompression(hdib))]);
  443. MessageBox(hwnd, szBuffer, szAppName, MB_ICONEXCLAMATION | MB_OK);
  444. return ;
  445. case IDM_APP_EXIT:
  446. SendMessage(hwnd, WM_CLOSE, , );
  447. return ;
  448. case IDM_EDIT_COPY:
  449. case IDM_EDIT_CUT:
  450. if (!(hGlobal = DibCopyToPackedDib(hdib, TRUE)))
  451. return ;
  452. OpenClipboard(hwnd);
  453. EmptyClipboard();
  454. SetClipboardData(CF_DIB, hGlobal);
  455. CloseClipboard();
  456. if (LOWORD(wParam) == IDM_EDIT_COPY)
  457. return ;
  458. //剪切时,继续执行下去
  459. case IDM_EDIT_DELETE:
  460. SendMessage(hwnd, WM_USER_DELETEDIB, , );
  461. InvalidateRect(hwnd, NULL, TRUE);
  462. return ;
  463. case IDM_EDIT_PASTE:
  464. OpenClipboard(hwnd);
  465. hGlobal = GetClipboardData(CF_DIB);
  466. pGlobal = GlobalLock(hGlobal);
  467. //如果己经存在DIB位图和调色板,则删除它们
  468. if (pGlobal)
  469. {
  470. SendMessage(hwnd, WM_USER_DELETEDIB, , );
  471. hdib = DibCopyFromPackedDib((BITMAPINFO*)pGlobal);
  472. SendMessage(hwnd, WM_USER_CREATEPAL, TRUE, );
  473. }
  474. GlobalUnlock(hGlobal);
  475. CloseClipboard();
  476. //重置滚动条
  477. SendMessage(hwnd, WM_USER_SETSCROLLS, TRUE, );
  478. InvalidateRect(hwnd, NULL, TRUE);
  479. return ;
  480. case IDM_EDIT_ROTATE:
  481. if (hdibNew = DibRotateRight(hdib))
  482. {
  483. DibDelete(hdib);
  484. DeleteObject(hBitmap);
  485. hdib = hdibNew;
  486. hBitmap = DibCopyToDdb(hdib, hwnd, hPalette);
  487. SendMessage(hwnd, WM_USER_SETSCROLLS, TRUE, );
  488. InvalidateRect(hwnd, NULL, TRUE);
  489. } else
  490. {
  491. MessageBox(hwnd, TEXT("Not enough memory"),
  492. szAppName, MB_OK | MB_ICONEXCLAMATION);
  493. }
  494. return ;
  495. case IDM_EDIT_FLIP:
  496. if (hdibNew = DibFlipHorizontal(hdib))
  497. {
  498. DibDelete(hdib);
  499. DeleteObject(hBitmap);
  500. hdib = hdibNew;
  501. hBitmap = DibCopyToDdb(hdib, hwnd, hPalette);
  502. InvalidateRect(hwnd, NULL, TRUE);
  503. } else
  504. {
  505. MessageBox(hwnd, TEXT("Not enough memory"),
  506. szAppName, MB_OK | MB_ICONEXCLAMATION);
  507. }
  508. return ;
  509.  
  510. case IDM_SHOW_NORMAL:
  511. case IDM_SHOW_STRETCH:
  512. case IDM_SHOW_CENTER:
  513. case IDM_SHOW_ISOSTRETCH:
  514. CheckMenuItem(hMenu, wShow, MF_UNCHECKED);
  515. wShow = LOWORD(wParam);
  516. CheckMenuItem(hMenu, wShow, MF_CHECKED);
  517. SendMessage(hwnd, WM_USER_SETSCROLLS, TRUE, );
  518. InvalidateRect(hwnd, NULL, TRUE);
  519. return ;
  520. case IDM_CONVERT_32:iConvert += ;
  521. case IDM_CONVERT_24:iConvert += ;
  522. case IDM_CONVERT_16:iConvert += ;
  523. case IDM_CONVERT_08:iConvert += ;
  524. case IDM_CONVERT_04:iConvert += ;
  525. case IDM_CONVERT_01:iConvert += ;
  526. SetCursor(LoadCursor(NULL, IDC_WAIT));
  527. ShowCursor(TRUE);
  528. hdibNew = DibConvert(hdib, iConvert);
  529. ShowCursor(FALSE);
  530. SetCursor(LoadCursor(NULL, IDC_ARROW));
  531. if (hdibNew)
  532. {
  533. SendMessage(hwnd, WM_USER_DELETEDIB, , );
  534. hdib = hdibNew;
  535. SendMessage(hwnd, WM_USER_CREATEPAL, TRUE, );
  536. InvalidateRect(hwnd, NULL, TRUE);
  537. } else
  538. {
  539. MessageBox(hwnd, TEXT("Not enough memory"),
  540. szAppName, MB_OK | MB_ICONEXCLAMATION);
  541. }
  542. return ;
  543. case IDM_APP_ABOUT:
  544. MessageBox(hwnd, TEXT("Dibble (c) Charles Petzold,1998"),
  545. szAppName, MB_OK | MB_ICONEXCLAMATION);
  546. return ;
  547. }
  548.  
  549. //其余所有的WM_COMMAND消息都是来自调色板项目。如果删除己经存在的调色板,光标将被
  550. //设置为沙漏的形状
  551. SendMessage(hwnd, WM_USER_DELETEPAL, , );
  552. SetCursor(LoadCursor(NULL, IDC_WAIT));
  553. ShowCursor(TRUE);
  554. //提醒,所有的调色板消息都以break结束而不是return,这允许后面进行一些额外的处理
  555. switch (LOWORD(wParam))
  556. {
  557. case IDM_PAL_DIBTABLE:
  558. hPalette = DibPalDibTable(hdib);
  559. break;
  560. case IDM_PAL_HALFTONE:
  561. hdc = GetDC(hwnd);
  562. if (hPalette = CreateHalftonePalette(hdc))
  563. fHalftonePalette = TRUE;
  564. ReleaseDC(hwnd, hdc);
  565. break;
  566. case IDM_PAL_ALLPURPOSE:
  567. hPalette = DibPalAllPurpose();
  568. break;
  569.  
  570. case IDM_PAL_GRAY2: hPalette = DibPalUniformGrays(); break;
  571. case IDM_PAL_GRAY3: hPalette = DibPalUniformGrays(); break;
  572. case IDM_PAL_GRAY4: hPalette = DibPalUniformGrays(); break;
  573. case IDM_PAL_GRAY8: hPalette = DibPalUniformGrays(); break;
  574. case IDM_PAL_GRAY16: hPalette = DibPalUniformGrays(); break;
  575. case IDM_PAL_GRAY32: hPalette = DibPalUniformGrays(); break;
  576. case IDM_PAL_GRAY64: hPalette = DibPalUniformGrays(); break;
  577. case IDM_PAL_GRAY128: hPalette = DibPalUniformGrays(); break;
  578. case IDM_PAL_GRAY256: hPalette = DibPalUniformGrays(); break;
  579. case IDM_PAL_RGB222: hPalette = DibPalUniformColors(, , ); break;
  580. case IDM_PAL_RGB333: hPalette = DibPalUniformColors(, , ); break;
  581. case IDM_PAL_RGB444: hPalette = DibPalUniformColors(, , ); break;
  582. case IDM_PAL_RGB555: hPalette = DibPalUniformColors(, , ); break;
  583. case IDM_PAL_RGB666: hPalette = DibPalUniformColors(, , ); break;
  584. case IDM_PAL_RGB775: hPalette = DibPalUniformColors(, , ); break;
  585. case IDM_PAL_RGB757: hPalette = DibPalUniformColors(, , ); break;
  586. case IDM_PAL_RGB577: hPalette = DibPalUniformColors(, , ); break;
  587. case IDM_PAL_RGB884: hPalette = DibPalUniformColors(, , ); break;
  588. case IDM_PAL_RGB848: hPalette = DibPalUniformColors(, , ); break;
  589. case IDM_PAL_RGB488: hPalette = DibPalUniformColors(, , ); break;
  590. case IDM_PAL_OPT_POP4:
  591. hPalette = DibPalPopularity(hdib, );
  592. break;
  593. case IDM_PAL_OPT_POP5:
  594. hPalette = DibPalPopularity(hdib, );
  595. break;
  596. case IDM_PAL_OPT_POP6:
  597. hPalette = DibPalPopularity(hdib, );
  598. break;
  599. case IDM_PAL_OPT_MEDCUT:
  600. hPalette = DibPalMedianCut(hdib, );
  601. break;
  602. }
  603. //当处理完菜单中的调色板项目后,光标恢复为箭头的形状,该项被设为Checked,并
  604. //且刷新客户区
  605. hBitmap = DibCopyToDdb(hdib, hwnd, hPalette);
  606. ShowCursor(FALSE);
  607. SetCursor(LoadCursor(NULL, IDC_ARROW));
  608. if (hPalette)
  609. PaletteMenu(hMenu, (LOWORD(wParam)));
  610. InvalidateRect(hwnd, NULL, TRUE);
  611. return ; //WM_COMMAND消息处理完毕
  612. //该消息中删除一个己经存在的DIB,为获取一个新DIB作准备。
  613. //该消息会被打开、粘贴或其它菜单命令所调用
  614. case WM_USER_DELETEDIB:
  615. if (hdib)
  616. {
  617. DibDelete(hdib);
  618. hdib = NULL;
  619. }
  620. SendMessage(hwnd, WM_USER_DELETEPAL, , );
  621. return ;
  622. //基于一个新DIB创建一个调色板。如果wParam==TRUE,则同时创建DDB
  623. case WM_USER_CREATEPAL:
  624. if (hdib)
  625. {
  626. hdc = GetDC(hwnd);
  627. if (!(RC_PALETTE & GetDeviceCaps(hdc, RASTERCAPS))) //不支持调色调
  628. {
  629. PaletteMenu(hMenu, IDM_PAL_NONE);
  630. } else if (hPalette = CreateHalftonePalette(hdc)) //创建半色调调色板
  631. {
  632. fHalftonePalette = TRUE;
  633. PaletteMenu(hMenu, IDM_PAL_HALFTONE);
  634. }
  635. ReleaseDC(hwnd, hdc);
  636. if ((BOOL)wParam)
  637. hBitmap = DibCopyToDdb(hdib, hwnd, hPalette);
  638. }
  639. return ;
  640.  
  641. //删除一个己经存在的调色板,为创建新调色板做准备
  642. case WM_USER_DELETEPAL:
  643. if (hPalette)
  644. {
  645. DeleteObject(hPalette);
  646. hPalette = NULL;
  647. fHalftonePalette = FALSE;
  648. PaletteMenu(hMenu, IDM_PAL_NONE);
  649. }
  650. if (hBitmap)
  651. {
  652. DeleteObject(hBitmap);
  653. }
  654. return ;
  655. case WM_PAINT:
  656. hdc = BeginPaint(hwnd, &ps);
  657. if (hPalette)
  658. {
  659. SelectPalette(hdc, hPalette, FALSE);
  660. RealizePalette(hdc);
  661. }
  662. if (hBitmap)
  663. {
  664. DisplayDib(hdc,
  665. fHalftonePalette ? DibBitmapHandle(hdib) : hBitmap,
  666. iHscroll, iVscroll,
  667. cxClient, cyClient,
  668. wShow, fHalftonePalette);
  669. }
  670.  
  671. EndPaint(hwnd, &ps);
  672. return ;
  673. case WM_QUERYNEWPALETTE:
  674. if (!hPalette)
  675. return FALSE;
  676. hdc = GetDC(hwnd);
  677. SelectPalette(hdc, hPalette, FALSE);
  678. RealizePalette(hdc);
  679. InvalidateRect(hwnd, NULL, TRUE);
  680. ReleaseDC(hwnd, hdc);
  681. return TRUE;
  682. case WM_PALETTECHANGED:
  683. if (!hPalette || (HWND)wParam == hwnd)
  684. return FALSE;
  685. hdc = GetDC(hwnd);
  686. SelectPalette(hdc, hPalette, FALSE);
  687. RealizePalette(hdc);
  688. UpdateColors(hdc);
  689. ReleaseDC(hwnd, hdc);
  690. break;
  691. case WM_DESTROY:
  692. if (hdib)
  693. DibDelete(hdib);
  694. if (hBitmap)
  695. DeleteObject(hBitmap);
  696. if (hPalette)
  697. DeleteObject(hPalette);
  698.  
  699. PostQuitMessage();
  700. return ;
  701. }
  702. return DefWindowProc(hwnd, message, wParam, lParam);
  703. }

//resource.h

  1. //{{NO_DEPENDENCIES}}
  2. // Microsoft Visual C++ 生成的包含文件。
  3. // 供 Dibble.rc 使用
  4. //
  5. #define IDM_FILE_OPEN 40001
  6. #define IDM_FILE_SAVE 40002
  7. #define IDM_FILE_PRINT 40003
  8. #define IDM_FILE_PROPERTIES 40004
  9. #define IDM_APP_EXIT 40005
  10. #define IDM_EDIT_CUT 40006
  11. #define IDM_EDIT_COPY 40007
  12. #define IDM_EDIT_PASTE 40008
  13. #define IDM_EDIT_DELETE 40009
  14. #define IDM_EDIT_FLIP 40010
  15. #define IDM_EDIT_ROTATE 40011
  16. #define IDM_SHOW_NORMAL 40012
  17. #define IDM_SHOW_CENTER 40013
  18. #define IDM_SHOW_STRETCH 40014
  19. #define IDM_SHOW_ISOSTRETCH 40015
  20. #define IDM_PAL_NONE 40016
  21. #define IDM_PAL_DIBTABLE 40017
  22. #define IDM_PAL_HALFTONE 40018
  23. #define IDM_PAL_ALLPURPOSE 40019
  24. #define IDM_PAL_GRAY2 40020
  25. #define IDM_PAL_GRAY3 40021
  26. #define IDM_PAL_GRAY4 40022
  27. #define IDM_PAL_GRAY8 40023
  28. #define IDM_PAL_GRAY16 40024
  29. #define IDM_PAL_GRAY32 40025
  30. #define IDM_PAL_GRAY64 40026
  31. #define IDM_PAL_GRAY128 40027
  32. #define IDM_PAL_GRAY256 40028
  33. #define IDM_PAL_RGB222 40029
  34. #define IDM_PAL_RGB333 40030
  35. #define IDM_PAL_RGB444 40031
  36. #define IDM_PAL_RGB555 40032
  37. #define IDM_PAL_RGB666 40033
  38. #define IDM_PAL_RGB775 40034
  39. #define IDM_PAL_RGB757 40035
  40. #define IDM_PAL_RGB577 40036
  41. #define IDM_PAL_RGB884 40037
  42. #define IDM_PAL_RGB848 40038
  43. #define IDM_PAL_RGB488 40039
  44. #define IDM_CONVERT_01 40040
  45. #define IDM_CONVERT_04 40041
  46. #define IDM_CONVERT_08 40042
  47. #define IDM_CONVERT_16 40043
  48. #define IDM_CONVERT_24 40044
  49. #define IDM_CONVERT_32 40045
  50. #define IDM_APP_ABOUT 40046
  51. #define IDM_PAL_OPT_POP4 40047
  52. #define IDM_PAL_OPT_POP5 40048
  53. #define IDM_PAL_OPT_POP6 40049
  54. #define IDM_PAL_OPT_MEDCUT 40050
  55. // Next default values for new objects
  56. //
  57. #ifdef APSTUDIO_INVOKED
  58. #ifndef APSTUDIO_READONLY_SYMBOLS
  59. #define _APS_NEXT_RESOURCE_VALUE 103
  60. #define _APS_NEXT_COMMAND_VALUE 40040
  61. #define _APS_NEXT_CONTROL_VALUE 1001
  62. #define _APS_NEXT_SYMED_VALUE 101
  63. #endif
  64. #endif

//Dibble.rc

  1. // Microsoft Visual C++ generated resource script.
  2. //
  3. #include "resource.h"
  4. #define APSTUDIO_READONLY_SYMBOLS
  5. /////////////////////////////////////////////////////////////////////////////
  6. //
  7. // Generated from the TEXTINCLUDE 2 resource.
  8. //
  9. #include "winres.h"
  10. /////////////////////////////////////////////////////////////////////////////
  11. #undef APSTUDIO_READONLY_SYMBOLS
  12. /////////////////////////////////////////////////////////////////////////////
  13. // 中文(简体,中国) resources
  14. #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
  15. LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
  16. #ifdef APSTUDIO_INVOKED
  17. /////////////////////////////////////////////////////////////////////////////
  18. //
  19. // TEXTINCLUDE
  20. //
  21. TEXTINCLUDE
  22. BEGIN
  23. "resource.h\0"
  24. END
  25. TEXTINCLUDE
  26. BEGIN
  27. "#include ""winres.h""\r\n"
  28. "\0"
  29. END
  30. TEXTINCLUDE
  31. BEGIN
  32. "\r\n"
  33. "\0"
  34. END
  35. #endif // APSTUDIO_INVOKED
  36. /////////////////////////////////////////////////////////////////////////////
  37. //
  38. // Menu
  39. //
  40. DIBBLE MENU
  41. BEGIN
  42. POPUP "&File"
  43. BEGIN
  44. MENUITEM "&Open...\tCtrl+O", IDM_FILE_OPEN
  45. MENUITEM "&Save...\tCtrl+S", IDM_FILE_SAVE
  46. MENUITEM SEPARATOR
  47. MENUITEM "&Print...\tCtrl+P", IDM_FILE_PRINT
  48. MENUITEM SEPARATOR
  49. MENUITEM "Propert&ies...", IDM_FILE_PROPERTIES
  50. MENUITEM SEPARATOR
  51. MENUITEM "E&xit", IDM_APP_EXIT
  52. END
  53. POPUP "&Edit"
  54. BEGIN
  55. MENUITEM "Cu&t\tCtrl+X", IDM_EDIT_CUT
  56. MENUITEM "&Copy\tCtrl+C", IDM_EDIT_COPY
  57. MENUITEM "&Paste\tCtrl+V", IDM_EDIT_PASTE
  58. MENUITEM "&Delete\tDelete", IDM_EDIT_DELETE
  59. MENUITEM SEPARATOR
  60. MENUITEM "&Flip", IDM_EDIT_FLIP
  61. MENUITEM "&Rotate", IDM_EDIT_ROTATE
  62. END
  63. POPUP "&Show"
  64. BEGIN
  65. MENUITEM "&Actual Size", IDM_SHOW_NORMAL, CHECKED
  66. MENUITEM "&Center", IDM_SHOW_CENTER
  67. MENUITEM "&Stretch to Window", IDM_SHOW_STRETCH
  68. MENUITEM "Stretch &Isotropically", IDM_SHOW_ISOSTRETCH
  69. END
  70. POPUP "&Palette"
  71. BEGIN
  72. MENUITEM "&None", IDM_PAL_NONE, CHECKED
  73. MENUITEM "&Dib ColorTable", IDM_PAL_DIBTABLE
  74. MENUITEM "&Halftone", IDM_PAL_HALFTONE
  75. MENUITEM "&All-Purpose", IDM_PAL_ALLPURPOSE
  76. POPUP "&Gray Shades"
  77. BEGIN
  78. MENUITEM "&1. 2 Grays ", IDM_PAL_GRAY2
  79. MENUITEM "&2. 3 Grays", IDM_PAL_GRAY3
  80. MENUITEM "&3. 4 Grays", IDM_PAL_GRAY4
  81. MENUITEM "&4. 8 Grays", IDM_PAL_GRAY8
  82. MENUITEM "&5. 16 Grays", IDM_PAL_GRAY16
  83. MENUITEM "&6. 32 Grays", IDM_PAL_GRAY32
  84. MENUITEM "&7. 64 Grays", IDM_PAL_GRAY64
  85. MENUITEM "&8. 128 Grays", IDM_PAL_GRAY128
  86. MENUITEM "&9. 256 Grays", IDM_PAL_GRAY256
  87. END
  88. POPUP "&Uniform Colors"
  89. BEGIN
  90. MENUITEM "&1. 2R×2G×2B (8)", IDM_PAL_RGB222
  91. MENUITEM "&2. 3R×3G×3B (27)", IDM_PAL_RGB333
  92. MENUITEM "&3. 4R×4G×4B (64)", IDM_PAL_RGB444
  93. MENUITEM "&4. 5R×5G×5B (125)", IDM_PAL_RGB555
  94. MENUITEM "&5. 6R×6G×6B (216)", IDM_PAL_RGB666
  95. MENUITEM "&6. 7R×7G×5B (245)", IDM_PAL_RGB775
  96. MENUITEM "&7. 7R×5G×7B (245)", IDM_PAL_RGB757
  97. MENUITEM "&8. 5R×7G×7B (245)", IDM_PAL_RGB577
  98. MENUITEM "&9. 8R×8G×4B (256)", IDM_PAL_RGB884
  99. MENUITEM "&A. 8R×4G×8B (256)", IDM_PAL_RGB848
  100. MENUITEM "&B. 4R×8G×8B (256)", IDM_PAL_RGB488
  101. END
  102. POPUP "&Optimized"
  103. BEGIN
  104. MENUITEM "&1. Popularity Algorithm (4 bits)", IDM_PAL_OPT_POP4
  105. MENUITEM "&2. Popularity Algorithm (5 bits)", IDM_PAL_OPT_POP5
  106. MENUITEM "&3. Popularity Algorithm (6 bits)", IDM_PAL_OPT_POP6
  107. MENUITEM "&4. Median Cut Algorithm (4 bits)", IDM_PAL_OPT_MEDCUT
  108. END
  109. END
  110. POPUP "Con&vert"
  111. BEGIN
  112. MENUITEM "&1. to 1 bit per pixel", IDM_CONVERT_01
  113. MENUITEM "&2. to 4 bits per Pixel", IDM_CONVERT_04
  114. MENUITEM "&3. to 8 bit per pixel", IDM_CONVERT_08
  115. MENUITEM "&4. to 16 bits per Pixel", IDM_CONVERT_16
  116. MENUITEM "&5. to 24 bit per pixel", IDM_CONVERT_24
  117. MENUITEM "&6. to 32 bits per Pixel", IDM_CONVERT_32
  118. END
  119. POPUP "&Help"
  120. BEGIN
  121. MENUITEM "&About", IDM_APP_ABOUT
  122. END
  123. END
  124. /////////////////////////////////////////////////////////////////////////////
  125. //
  126. // Accelerator
  127. //
  128. DIBBLE ACCELERATORS
  129. BEGIN
  130. "C", IDM_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
  131. "X", IDM_EDIT_CUT, VIRTKEY, CONTROL, NOINVERT
  132. VK_DELETE, IDM_EDIT_DELETE, VIRTKEY, NOINVERT
  133. "V", IDM_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT
  134. "O", IDM_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
  135. "P", IDM_FILE_PRINT, VIRTKEY, CONTROL, NOINVERT
  136. "S", IDM_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT
  137. END
  138. #endif // 中文(简体,中国) resources
  139. /////////////////////////////////////////////////////////////////////////////
  140. #ifndef APSTUDIO_INVOKED
  141. /////////////////////////////////////////////////////////////////////////////
  142. //
  143. // Generated from the TEXTINCLUDE 3 resource.
  144. //
  145. /////////////////////////////////////////////////////////////////////////////
  146. #endif // not APSTUDIO_INVOKED

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//

  1. /*--------------------------------------------------------
  2. DIBHELP.H Header file for DIBHELP.C
  3. --------------------------------------------------------*/
  4. #pragma once
  5. #include <windows.h>
  6. typedef void* HDIB;
  7. //DIBHELP.C中的函数
  8. BOOL DibIsValid(HDIB hdib); //Dib文件是否有效
  9. HBITMAP DibBitmapHandle(HDIB hdib);
  10. int DibWidth(HDIB hdib);
  11. int DibHeight(HDIB hdib);
  12. int DibBitCount(HDIB hdib);
  13. int DibRowLength(HDIB hdib); //每行像素数:4的倍数
  14. int DibNumColors(HDIB hdib);
  15. DWORD DibMask(HDIB hdib, int i);//获取颜色掩码
  16. int DibRShift(HDIB hdib, int i);//
  17. int DibLShift(HDIB hdib, int i);
  18. int DibCompression(HDIB hdib); //获取biCompression字段的值
  19. BOOL DibIsAddressable(HDIB hdib);//是否被压缩,DibIsNotCompressed
  20. DWORD DibInfoHeaderSize(HDIB hdib);
  21. DWORD DibMaskSize(HDIB hdib);
  22. DWORD DibColorSize(HDIB hdib);
  23. DWORD DibInfoSize(HDIB hdib);
  24. DWORD DibBitsSize(HDIB hdib);
  25. DWORD DibTotalSize(HDIB hdib);
  26. BITMAPINFOHEADER* DibInfoHeaderPtr(HDIB hdib);
  27. DWORD* DibMaskPtr(HDIB hdib);
  28. void* DibBitsPtr(HDIB hdib);
  29. BOOL DibGetColor(HDIB hdib, int index, RGBQUAD* prgb);
  30. BOOL DibSetColor(HDIB hdib, int index, RGBQUAD*prgb);
  31. BYTE* DibPixelPtr(HDIB hdib, int x, int y);
  32. DWORD DibGetPixel(HDIB hdib, int x, int y);
  33. BOOL DibSetPixel(HDIB hdib, int x, int y, DWORD dwPixel);
  34. BOOL DibGetPixelColor(HDIB hdib, int x, int y, RGBQUAD* prgb);
  35. BOOL DibSetPixelColor(HDIB hdib, int x, int y, RGBQUAD* prgb);
  36. HDIB DibCreateFromInfo(BITMAPINFO* pbmi);
  37. BOOL DibDelete(HDIB hdib);
  38. HDIB DibCreate(int cx, int cy, int cBits, int cColors);
  39. HDIB DibCopy(HDIB hdibSrc, BOOL fRotate);
  40. BITMAPINFO* DibCopyToPackedDib(HDIB hdib, BOOL fUsedGlobal);
  41. HDIB DibCopyFromPackedDib(BITMAPINFO* pPackedDib);
  42. HDIB DibFileLoad(const TCHAR* szFileName);
  43. BOOL DibFileSave(HDIB hdib, const TCHAR* szFileName);
  44. HBITMAP DibCopyToDdb(HDIB hdib, HWND hwnd, HPALETTE hPalette);
  45. HDIB DibCreateFromDdb(HBITMAP hBitmap); //该函数课本没有给出实现
  46. /*----------------------------------------------------------
  47. DibFlipHorizontal:调用没有优化的DibSetPixel和DibGetPixel
  48. ----------------------------------------------------------*/
  49. HDIB DibFlipHorizontal(HDIB hdibSrc);
  50. /*----------------------------------------------------------
  51. DibRotateRight:调用优化过的DibSetPixelx和DibGetPixelx
  52. ----------------------------------------------------------*/
  53. HDIB DibRotateRight(HDIB hdibSrc);
  54. /*----------------------------------------------------------
  55. 快速无边界检查的gets和Sets宏
  56. ----------------------------------------------------------*/
  57. #define DibPixelPtr1(hdib,x,y) (((*(PBYTE**)hdib)[y]) +((x)>>3))
  58. #define DibPixelPtr4(hdib,x,y) (((*(PBYTE**)hdib)[y]) +((x)>>1))
  59. #define DibPixelPtr8(hdib,x,y) (((*(PBYTE**)hdib)[y]) + (x) )
  60. #define DibPixelPtr16(hdib,x,y) ((WORD*)(((*(PBYTE**)hdib)[y]) + (x)*2 ))
  61. #define DibPixelPtr24(hdib,x,y) ((RGBTRIPLE*)(((*(PBYTE**)hdib)[y]) + (x)*3 ))
  62. #define DibPixelPtr32(hdib,x,y) ((DWORD*)(((*(PBYTE**)hdib)[y]) + (x)*4 ))
  63. #define DibGetPixel1(hdib,x,y) (0x01&(*DibPixelPtr1(hdib,x,y) >> (7 -((x)&7))))
  64. #define DibGetPixel4(hdib,x,y) (0x0F &(*DibPixelPtr4(hdib,x,y)>>((x)&1 ? 0 : 4)))
  65. #define DibGetPixel8(hdib,x,y) (*DibPixelPtr8(hdib,x,y))
  66. #define DibGetPixel16(hdib,x,y) (*DibPixelPtr16(hdib,x,y))
  67. #define DibGetPixel24(hdib,x,y) (*DibPixelPtr24(hdib,x,y))
  68. #define DibGetPixel32(hdib,x,y) (*DibPixelPtr32(hdib,x,y))
  69. #define DibSetPixel1(hdib, x, y, p) \
  70. ((*DibPixelPtr1(hdib, x, y) &= ~( << ( - ((x)& )))), \
  71. (*DibPixelPtr1(hdib, x, y) |= ((p) << ( - ((x)& )))))
  72. #define DibSetPixel4(hdib, x, y, p) \
  73. ((*DibPixelPtr4(hdib, x, y) &= (0x0F << ((x)& ? : ))), \
  74. (*DibPixelPtr4(hdib, x, y) |= ((p) << ((x)& ? : ))))
  75. #define DibSetPixel8(hdib, x, y, p) (* DibPixelPtr8 (hdib, x, y) = p)
  76. #define DibSetPixel16(hdib, x, y, p) (* DibPixelPtr16 (hdib, x, y) = p)
  77. #define DibSetPixel24(hdib, x, y, p) (* DibPixelPtr24 (hdib, x, y) = p)
  78. #define DibSetPixel32(hdib, x, y, p) (* DibPixelPtr32 (hdib, x, y) = p)

//DibHelp.c

  1. /*-------------------------------------------------------------
  2. DIBHELP.C -- DIB Section Helper Routines
  3. (c)Charles Petzold,1998
  4. -------------------------------------------------------------*/
  5. #include <windows.h>
  6. #include "DibHelp.h"
  7. #define HDIB_SIGNATURE (*(int*)"Dib ")
  8. typedef struct
  9. {
  10. PBYTE* ppRow; //像素位的行指针,必须是第一个字段,为后面的宏操作更容易设计的。
  11. //第一个指针指向DIB位图视觉上最上面的一行像素,最后一个指针指向
  12. //DIB图像最后一行的像素,和pBits字段一样(也就是pBits也要被存成
  13. //这样的格式)
  14. int iSignature; //="Dib "
  15. HBITMAP hBitmap;//接收从CreateDIBSection返回的句柄,明显返回的是设备无关的位图,
  16. //但可以直接被BitBlt或StretchBlt
  17. BYTE* pBits; //指向位图的像素数据,其值在CreateDIBSection函数中被设定。其所指
  18. //的内存块由操作系统管理,但应用程序可以访问该内存块。删除位图
  19. //句柄后,该内存块自动被删除
  20. DIBSECTION ds; //可以用GetObject获得位图信图,存入该结构体
  21. int iRShift[]; //分别存入R、G、B3种颜色遮罩需左移的值
  22. int iLShift[]; //
  23. }DIBSTRUCT, *PDIBSTRUCT;
  24. /*----------------------------------------------------------------------------------
  25. DibIsValid:如果hdib指向一个有效的DIBSTRUCT结构体时返回TRUE
  26. -----------------------------------------------------------------------------------*/
  27. BOOL DibIsValid(HDIB hdib)
  28. {
  29. DIBSTRUCT* pdib = hdib;
  30. if (pdib == NULL)
  31. return FALSE;
  32. //检查是否有读取指定内存的内容的权限,参数1为要检查的内存指针,参数2为要检查的内存块大小
  33. if (IsBadReadPtr(pdib, sizeof(DIBSTRUCT)))
  34. return FALSE;
  35. if (pdib->iSignature != HDIB_SIGNATURE) //自定义的DIB位图标识符
  36. return FALSE;
  37. return TRUE;
  38. }
  39. /*----------------------------------------------------------------------------------
  40. DibBitmapHandle:返回DIB Section位图对象的句柄hBitmap
  41. -----------------------------------------------------------------------------------*/
  42. HBITMAP DibBitmapHandle(HDIB hdib)
  43. {
  44. if (!DibIsValid(hdib))
  45. return NULL;
  46. return ((PDIBSTRUCT)hdib)->hBitmap;
  47. }
  48. /*----------------------------------------------------------------------------------
  49. DibWidth:返回位图的宽度(单位字节)
  50. -----------------------------------------------------------------------------------*/
  51. int DibWidth(HDIB hdib)
  52. {
  53. if (!DibIsValid(hdib))
  54. return ;
  55. return ((PDIBSTRUCT)hdib)->ds.dsBm.bmWidth;
  56. }
  57. /*----------------------------------------------------------------------------------
  58. DibHeight:返回位图的高度(单位字节)
  59. -----------------------------------------------------------------------------------*/
  60. int DibHeight(HDIB hdib)
  61. {
  62. if (!DibIsValid(hdib))
  63. return ;
  64. return ((PDIBSTRUCT)hdib)->ds.dsBm.bmHeight;
  65. }
  66. /*----------------------------------------------------------------------------------
  67. DibBitCount:返回每像素的位数
  68. -----------------------------------------------------------------------------------*/
  69. int DibBitCount(HDIB hdib)
  70. {
  71. if (!DibIsValid(hdib))
  72. return ;
  73. return ((PDIBSTRUCT)hdib)->ds.dsBm.bmBitsPixel;
  74. }
  75. /*----------------------------------------------------------------------------------
  76. DibRowLength:返回每行像素的大小(单位:字节):4的倍数
  77. -----------------------------------------------------------------------------------*/
  78. int DibRowLength(HDIB hdib)
  79. {
  80. if (!DibIsValid(hdib))
  81. return ;
  82. return * ((DibWidth(hdib)*DibBitCount(hdib) + ) / );
  83. }
  84. /*----------------------------------------------------------------------------------
  85. DibNumColors:返回颜色表的颜色数目,无颜色表时返回0
  86. -----------------------------------------------------------------------------------*/
  87. int DibNumColors(HDIB hdib)
  88. {
  89. PDIBSTRUCT pdib = hdib;
  90. if (!DibIsValid(hdib))
  91. return ;
  92. if (pdib->ds.dsBmih.biClrUsed != )
  93. {
  94. return pdib->ds.dsBmih.biClrUsed;
  95. } else if (DibBitCount(hdib) <= )
  96. {
  97. return << DibBitCount(hdib); //2^bBitCount,如1位则2种颜色,8位256色
  98. }
  99. return ;
  100. }
  101. /*----------------------------------------------------------------------------------
  102. DibMask:返回3种颜色遮罩其中的一种,如红色遮罩
  103. -----------------------------------------------------------------------------------*/
  104. DWORD DibMask(HDIB hdib, int i)
  105. {
  106. PDIBSTRUCT pdib = hdib;
  107. if (!DibIsValid(hdib) || i< || i>)
  108. return ;
  109. return pdib->ds.dsBitfields[i];//0—红色;1—绿色;2—蓝色
  110. }
  111. /*----------------------------------------------------------------------------------
  112. DibRShift:返回需右移的位数
  113. -----------------------------------------------------------------------------------*/
  114. int DibRShift(HDIB hdib, int i)
  115. {
  116. PDIBSTRUCT pdib = hdib;
  117. if (!DibIsValid(hdib) || i< || i>)
  118. return ;
  119. return pdib->iRShift[i];
  120. }
  121. /*----------------------------------------------------------------------------------
  122. DibLShift:返回需左移的位数
  123. -----------------------------------------------------------------------------------*/
  124. int DibLShift(HDIB hdib, int i)
  125. {
  126. PDIBSTRUCT pdib = hdib;
  127. if (!DibIsValid(hdib) || i< || i>)
  128. return ;
  129. return pdib->iLShift[i];
  130. }
  131. /*----------------------------------------------------------------------------------
  132. DibCompression: 获取biCompression字段的值
  133. -----------------------------------------------------------------------------------*/
  134. int DibCompression(HDIB hdib)
  135. {
  136. if (!DibIsValid(hdib))
  137. return ;
  138. return ((PDIBSTRUCT)hdib)->ds.dsBmih.biCompression;
  139. }
  140. //是否被压缩,DibIsNotCompressed
  141. /*----------------------------------------------------------------------------------
  142. DibIsAddressable: 如果DIB没压缩则返回TRUE
  143. -----------------------------------------------------------------------------------*/
  144. BOOL DibIsAddressable(HDIB hdib)
  145. {
  146. int iCompression;
  147. if (!DibIsValid(hdib))
  148. return ;
  149. iCompression = DibCompression(hdib);
  150.  
  151. if (iCompression == BI_RGB || iCompression == BI_BITFIELDS)
  152. return TRUE;
  153. return FALSE;
  154. }
  155. /*----------------------------------------------------------------------------------
  156. 下面这些函数返回DIB Section可能出现的各种变量信息,这些函数的目的是为了将DIB Section
  157. 转换为紧凑DIB或保存文件时使用
  158. -----------------------------------------------------------------------------------*/
  159. DWORD DibInfoHeaderSize(HDIB hdib) //文件信息头BITMAPINFOHEADER(不含颜色遮罩、颜色表)等
  160. {
  161. if (!DibIsValid(hdib))
  162. return ;
  163.  
  164. return ((PDIBSTRUCT)hdib)->ds.dsBmih.biSize;
  165. }
  166. DWORD DibMaskSize(HDIB hdib)
  167. {
  168. PDIBSTRUCT pdib = hdib;
  169. if (!DibIsValid(hdib))
  170. return ;
  171. if (pdib->ds.dsBmih.biCompression == BI_BITFIELDS)
  172. return * sizeof(DWORD);
  173. return ;
  174. }
  175. DWORD DibColorSize(HDIB hdib)
  176. {
  177. return DibNumColors(hdib)*sizeof(RGBQUAD);
  178. }
  179. DWORD DibInfoSize(HDIB hdib)
  180. {
  181. return DibInfoHeaderSize(hdib) + DibMaskSize(hdib) + DibColorSize(hdib);
  182. }
  183. DWORD DibBitsSize(HDIB hdib)
  184. {
  185. PDIBSTRUCT pdib = hdib;
  186. if (!DibIsValid(hdib))
  187. return ;
  188. if (pdib->ds.dsBmih.biSizeImage != )
  189. {
  190. return pdib->ds.dsBmih.biSizeImage;
  191. }
  192. return DibHeight(hdib)*DibRowLength(hdib);
  193. }
  194. DWORD DibTotalSize(HDIB hdib) //整个紧凑型DIB的大小
  195. {
  196. return DibInfoSize(hdib) + DibBitsSize(hdib);
  197. }
  198. /*----------------------------------------------------------------------------------
  199. 下面这些函数返回DIB Section各部分的指针
  200. -----------------------------------------------------------------------------------*/
  201. BITMAPINFOHEADER* DibInfoHeaderPtr(HDIB hdib)
  202. {
  203. if (!DibIsValid(hdib))
  204. return NULL;
  205. return &(((PDIBSTRUCT)hdib)->ds.dsBmih);
  206. }
  207. DWORD* DibMaskPtr(HDIB hdib)
  208. {
  209. PDIBSTRUCT pdib = hdib;
  210. if (!DibIsValid(hdib))
  211. return NULL;
  212. return pdib->ds.dsBitfields;//因为这个字段是个数组,数组名是个指针。
  213. }
  214. void* DibBitsPtr(HDIB hdib)
  215. {
  216. if (!DibIsValid(hdib))
  217. return NULL;
  218. return ((PDIBSTRUCT)hdib)->pBits;
  219. }
  220. /*----------------------------------------------------------------------------------
  221. DibGetColor:从DIB颜色表中获得指定索引号处的颜色,放在prgb结构体中
  222. -----------------------------------------------------------------------------------*/
  223. BOOL DibGetColor(HDIB hdib, int index, RGBQUAD* prgb)
  224. {
  225. PDIBSTRUCT pdib = hdib;
  226. HDC hdcMem;
  227. int iReturn;
  228. if (!DibIsValid(hdib))
  229. return FALSE;
  230. hdcMem = CreateCompatibleDC(NULL);
  231. SelectObject(hdcMem, pdib->hBitmap);
  232. iReturn = GetDIBColorTable(hdcMem, index, , prgb); //API函数
  233. DeleteDC(hdcMem);
  234. return iReturn ? TRUE : FALSE;
  235. }
  236. /*----------------------------------------------------------------------------------
  237. DibSetColor:prgb结构体颜色设置到DIB颜色表中
  238. -----------------------------------------------------------------------------------*/
  239. BOOL DibSetColor(HDIB hdib, int index, RGBQUAD*prgb)
  240. {
  241. PDIBSTRUCT pdib = hdib;
  242. HDC hdcMem;
  243. int iReturn;
  244. if (!DibIsValid(hdib))
  245. return FALSE;
  246. hdcMem = CreateCompatibleDC(NULL);
  247. SelectObject(hdcMem, pdib->hBitmap);
  248. iReturn = SetDIBColorTable(hdcMem, index, , prgb); //API函数
  249. DeleteDC(hdcMem);
  250. return iReturn ? TRUE : FALSE;
  251. }
  252. /*----------------------------------------------------------------------------------
  253. DibPixelPtr:返回(x,y)处的像素位指针
  254. -----------------------------------------------------------------------------------*/
  255. BYTE* DibPixelPtr(HDIB hdib, int x, int y)
  256. {
  257. if (!DibIsAddressable(hdib))
  258. return NULL;
  259. if (x < || x >= DibWidth(hdib) || y < || y >= DibHeight(hdib))
  260. return NULL;
  261. //x每次加1时,指针后移BitCount/8个字节,所以对于每像素1或4位时,
  262. //获取每个字节的像素还需移位才能读出像素值
  263. //对于8、16、24或32位的,每bitCount/8个字节
  264. //具体的处理 见DibGetPixel或DibSetPixel函数的处理。
  265. return (((PDIBSTRUCT)hdib)->ppRow)[y] + (x* DibBitCount(hdib) >> );
  266. }
  267. /*----------------------------------------------------------------------------------
  268. DibGetPixel:返回(x,y)处的像素值
  269. -----------------------------------------------------------------------------------*/
  270. DWORD DibGetPixel(HDIB hdib, int x, int y)
  271. {
  272. PBYTE pPixel;
  273. pPixel = DibPixelPtr(hdib, x, y);
  274. if (!pPixel)
  275. return ;
  276. switch (DibBitCount(hdib))
  277. {
  278. //快速求余法:X % (2^N) == X & (2^N - 1),
  279. case : return 0x01 & (*pPixel >> ( - (x & )));
  280. case : return 0x0F & (*pPixel >> (x & ? : ));//x为奇数是,取低4位,偶数取高4位
  281. case : return *pPixel;
  282. case :return *(WORD*)pPixel;
  283. case :return 0x00FFFFFF & *(DWORD*)pPixel;
  284. case :return *(DWORD*)pPixel;
  285. }
  286. return ;
  287. }
  288. /*----------------------------------------------------------------------------------
  289. DibSetPixel:设置(x,y)处的像素值
  290. -----------------------------------------------------------------------------------*/
  291. BOOL DibSetPixel(HDIB hdib, int x, int y, DWORD dwPixel)
  292. {
  293. PBYTE pPixel;
  294. pPixel = DibPixelPtr(hdib, x, y);
  295. if (!pPixel)
  296. return FALSE;
  297. switch (DibBitCount(hdib))
  298. {
  299. case :
  300. *pPixel &= ~( << ( - (x & ))); //取出该字节中除x处外的其余像素数
  301. *pPixel |= dwPixel << ( - (x & ));//将颜色值加入上述的X处。
  302. break;
  303. case :
  304. *pPixel &= 0x0F << (x & ? : );
  305. *pPixel |= dwPixel << (x & ? : );
  306. break;
  307.  
  308. case :
  309. *pPixel = (BYTE)dwPixel;
  310. break;
  311. case :
  312. *(WORD*)pPixel = (WORD)dwPixel;
  313. break;
  314. case :
  315. *(RGBTRIPLE*)pPixel = *(RGBTRIPLE*)&dwPixel;
  316. break;
  317. case :
  318. *(DWORD*)pPixel = dwPixel;
  319. break;
  320. default:
  321. return FALSE;
  322. }
  323. return TRUE;
  324. }
  325. /*----------------------------------------------------------------------------------
  326. DibGetPixelColor:获得(x,y)处的颜色值,并放入prgb所指的结构体中
  327. -----------------------------------------------------------------------------------*/
  328. BOOL DibGetPixelColor(HDIB hdib, int x, int y, RGBQUAD* prgb)
  329. {
  330. DWORD dwPixel;
  331. int iBitCount;
  332. PDIBSTRUCT pdib = hdib;
  333. //获得每像素位的大小,也可以使用它来作有效性验证
  334. if ( == (iBitCount = DibBitCount(hdib)))
  335. return FALSE;
  336. //获取像素位的值,返回DWORD,该值可能是索引或里面含有RGB值
  337. dwPixel = DibGetPixel(hdib, x, y);
  338. //如果是8位或以下的,该值为颜色表索引
  339. if (iBitCount <= )
  340. return DibGetColor(hdib, (int)dwPixel, prgb);
  341. else if (iBitCount == )
  342. {
  343. *(RGBTRIPLE*)prgb = *(RGBTRIPLE*)&dwPixel;
  344. prgb->rgbReserved = ;
  345. } else if (iBitCount == && pdib->ds.dsBmih.biCompression == BI_RGB)
  346. {
  347. *prgb = *(RGBQUAD*)&dwPixel;
  348. }
  349. //此外的情况,使用颜色遮罩和移位
  350. else
  351. {
  352. //下面等号右边的式子,执行顺序先用掩码取出dwPixel的相应颜色,再右移,最后左移。
  353. prgb->rgbRed = (BYTE)((pdib->ds.dsBitfields[] & dwPixel) >> pdib->iRShift[] << pdib->iLShift[]);
  354. prgb->rgbGreen = (BYTE)((pdib->ds.dsBitfields[] & dwPixel) >> pdib->iRShift[] << pdib->iLShift[]);
  355. prgb->rgbBlue = (BYTE)((pdib->ds.dsBitfields[] & dwPixel) >> pdib->iRShift[] << pdib->iLShift[]);
  356. }
  357. return TRUE;
  358. }
  359. /*----------------------------------------------------------------------------------
  360. DibSetPixelColor:获得(x,y)处的颜色值
  361. -----------------------------------------------------------------------------------*/
  362. BOOL DibSetPixelColor(HDIB hdib, int x, int y, RGBQUAD* prgb)
  363. {
  364. DWORD dwPixel;
  365. int iBitCount;
  366. PDIBSTRUCT pdib = hdib;
  367. //不要利用DIBs的颜色表来执行该函数的操作
  368. iBitCount = DibBitCount(hdib);
  369. if (iBitCount <= )
  370. return FALSE;
  371. //剩下来的步骤与GetPixelColor相反
  372. else if (iBitCount == )
  373. {
  374. *(RGBTRIPLE*)&dwPixel = *(RGBTRIPLE*)prgb;
  375. dwPixel &= 0x00FFFFFF;
  376. } else if (iBitCount == && pdib->ds.dsBmih.biCompression == BI_RGB)
  377. {
  378. *(RGBQUAD*)&dwPixel = *prgb;
  379. } else
  380. {
  381. //先将rgbRed由字节转为DWORD,再右移,最后左移
  382. dwPixel = (((DWORD)prgb->rgbRed >> pdib->iLShift[]) << pdib->iRShift[]);
  383. dwPixel |= (((DWORD)prgb->rgbGreen >> pdib->iLShift[]) << pdib->iRShift[]);
  384. dwPixel |= (((DWORD)prgb->rgbBlue >> pdib->iLShift[]) << pdib->iRShift[]);
  385. }
  386. DibSetPixel(hdib, x, y, dwPixel);
  387. return TRUE;
  388. }
  389. /*----------------------------------------------------------------------------------
  390. 根据遮罩颜色计算移位值,这些颜色遮罩来自于DibCreateFromInfo函数
  391. -----------------------------------------------------------------------------------*/
  392. static int MaskToRShift(DWORD dwMask)
  393. {
  394. int iShift;
  395. if ( == dwMask)
  396. return ;
  397. for (iShift = ; !(dwMask & ); iShift++) //最低位为0,则右移1位
  398. dwMask >>= ;
  399. return iShift;
  400. }
  401. static int MaskToLShift(DWORD dwMask)
  402. {
  403. int iShift;
  404. if ( == dwMask)
  405. return ;
  406. while (!(dwMask & )) //dwMask右侧的0移掉
  407. dwMask >>= ;
  408. for (iShift = ; dwMask & ; iShift++) //统计1的个数
  409. dwMask >>= ;
  410. return - iShift;
  411. }
  412. /*----------------------------------------------------------------------------------
  413. DibCreateFromInfo:
  414. 所有创建DIB的函数最后都要调用该函数。这个函数负责调用CreateDIBSection,
  415. 为DIBSTRUCT分配内存,并设置行指针
  416. -----------------------------------------------------------------------------------*/
  417. HDIB DibCreateFromInfo(BITMAPINFO* pbmi)
  418. {
  419. DIBSTRUCT* pdib;
  420. BYTE* pBits;
  421. HBITMAP hBitmap;
  422. int i, y, cy, iRowLength;
  423. //根据pbmi创建DIB Section位图,pBits指向今后要存入的像素位的空间地址(由系统管理)
  424. hBitmap = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, &pBits, NULL, );
  425. if (NULL == hBitmap)
  426. return NULL;
  427. if (NULL == (pdib = malloc(sizeof(DIBSTRUCT))))
  428. {
  429. DeleteObject(hBitmap);
  430. return NULL;
  431. }
  432. pdib->iSignature = HDIB_SIGNATURE;
  433. pdib->hBitmap = hBitmap;
  434. pdib->pBits = pBits;
  435.  
  436. //填充DIBSECTION结构
  437. GetObject(hBitmap, sizeof(DIBSECTION), &pdib->ds);
  438. //现在可以使用自定义的DIB信息函数,如DibCompression
  439. //如果压缩格式是BI_BITFIELDS,则计算掩码的移位
  440. if (DibCompression(pdib) == BI_BITFIELDS)
  441. {
  442. for (i = ; i < ; i++)
  443. {
  444. pdib->iLShift[i] = MaskToLShift(pdib->ds.dsBitfields[i]);
  445. pdib->iRShift[i] = MaskToRShift(pdib->ds.dsBitfields[i]);
  446. }
  447. }
  448. //如果是BI_RGB,但是16位或32位的,则设置bitFields和masks字段
  449. else if (DibCompression(pdib) == BI_RGB)
  450. {
  451. if (DibBitCount(pdib) == ) //RGB分别使用5-5-5型遮罩
  452. {
  453. pdib->ds.dsBitfields[] = 0x00007C00; //R Mask
  454. pdib->ds.dsBitfields[] = 0x000003E0; //G Mask
  455. pdib->ds.dsBitfields[] = 0x0000001F; //B Mask
  456. pdib->iRShift[] = ;
  457. pdib->iRShift[] = ;
  458. pdib->iRShift[] = ;
  459. pdib->iLShift[] = ;
  460. pdib->iLShift[] = ;
  461. pdib->iLShift[] = ;
  462. } else if (DibBitCount(pdib) == || DibBitCount(pdib) == ) //使用8-8-8型
  463. {
  464. pdib->ds.dsBitfields[] = 0x00FF0000; //R Mask
  465. pdib->ds.dsBitfields[] = 0x0000FF00; //G Mask
  466. pdib->ds.dsBitfields[] = 0x000000FF; //B Mask
  467. pdib->iRShift[] = ;
  468. pdib->iRShift[] = ;
  469. pdib->iRShift[] = ;
  470. pdib->iLShift[] = ;
  471. pdib->iLShift[] = ;
  472. pdib->iLShift[] = ;
  473. }
  474. }
  475. //分配DIB像素行指针数组
  476. cy = DibHeight(pdib);
  477. pdib->ppRow = malloc(cy*sizeof(BYTE*));
  478. if (NULL == pdib->ppRow)
  479. {
  480. free(pdib);
  481. DeleteObject(hBitmap);
  482. return NULL;
  483. }
  484. //初始化像素行指针数组,ppRow[0]设为图像视觉上的最顶行。
  485. iRowLength = DibRowLength(pdib);
  486. if (pbmi->bmiHeader.biHeight>) //位图从下到上存储
  487. {
  488. for (y = ; y < cy; y++)
  489. pdib->ppRow[y] = pBits + (cy - - y)*iRowLength;
  490. } else //从上到下存储
  491. {
  492. for (y = ; y < cy; y++)
  493. pdib->ppRow[y] = pBits + y*iRowLength;
  494. }
  495. return pdib;
  496. }
  497. /*----------------------------------------------------------------------------------
  498. DibDelete:删除DIBSTRUCT和在其中分配的内存
  499. -----------------------------------------------------------------------------------*/
  500. BOOL DibDelete(HDIB hdib)
  501. {
  502. DIBSTRUCT* pdib = hdib;
  503. if (!DibIsValid(hdib))
  504. return FALSE;
  505. free(pdib->ppRow);
  506. DeleteObject(pdib->hBitmap);
  507. free(pdib);
  508. return TRUE;
  509. }
  510. /*-----------------------------------------------------------------------------------
  511. DibCreate: 通过显式指定参数来构建HDIB()
  512. -----------------------------------------------------------------------------------*/
  513. HDIB DibCreate(int cx, int cy, int cBits, int cColors)
  514. {
  515. HDIB hdib;
  516. BITMAPINFO* pbmi;
  517. DWORD dwInfoSize;
  518. int cEntries = ;
  519. if (cx <= || cy <= ||
  520. ((cBits != ) && (cBits != ) && (cBits != ) &&
  521. (cBits != ) && (cBits != ) && (cBits != )))
  522. {
  523. return NULL;
  524. }
  525. if (cColors != )
  526. cEntries = cColors;
  527. else if (cBits <= )
  528. cEntries = << cBits;
  529. dwInfoSize = sizeof(BITMAPINFOHEADER) + (cEntries - )*sizeof(RGBQUAD);
  530. if (NULL == (pbmi = malloc(dwInfoSize)))
  531. {
  532. return NULL;
  533. }
  534. ZeroMemory(pbmi, dwInfoSize);
  535. pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  536. pbmi->bmiHeader.biWidth = cx;
  537. pbmi->bmiHeader.biHeight = cy;
  538. pbmi->bmiHeader.biPlanes = ;
  539. pbmi->bmiHeader.biBitCount = cBits;
  540. pbmi->bmiHeader.biCompression = BI_RGB;
  541. pbmi->bmiHeader.biSizeImage = ;
  542. pbmi->bmiHeader.biXPelsPerMeter = ;
  543. pbmi->bmiHeader.biYPelsPerMeter = ;
  544. pbmi->bmiHeader.biClrUsed = cColors;
  545. pbmi->bmiHeader.biClrImportant = ;
  546. hdib = DibCreateFromInfo(pbmi);
  547. free(pbmi);
  548. return hdib;
  549. }
  550. /*-----------------------------------------------------------------------------------
  551. DibCopyToInfo: 构建BITMAPINFO结构体.(主要供DibCopy和DibCopyToDdb函数使用)
  552. -----------------------------------------------------------------------------------*/
  553. static BITMAPINFO* DibCopyToInfo(HDIB hdib)
  554. {
  555. BITMAPINFO* pbmi;
  556. RGBQUAD* prgb;
  557. int i, iNumColors;
  558. if (!DibIsValid(hdib))
  559. return NULL;
  560. if (NULL == (pbmi = malloc(DibInfoSize(hdib))))
  561. return NULL;
  562.  
  563. //复制BITMAPINFO信息头部分
  564. CopyMemory(pbmi, DibInfoHeaderPtr(hdib), sizeof(BITMAPINFOHEADER));
  565. //复制可能的颜色遮罩
  566. prgb = (RGBQUAD*)((BYTE*)pbmi + sizeof(BITMAPINFOHEADER));
  567. if (DibMaskSize(hdib))
  568. {
  569. CopyMemory(prgb, DibMaskPtr(hdib), * sizeof(DWORD));
  570. prgb = (RGBQUAD*)((BYTE*)prgb + * sizeof(DWORD));//将指针移到遮罩后,指向颜色表
  571. }
  572. //复制颜色表
  573. iNumColors = DibNumColors(hdib);
  574. for (i = ; i < iNumColors; i++)
  575. {
  576. DibGetColor(hdib, i, prgb + i); //每种颜色都是32位的。RGRQUAD也是32位的
  577. }
  578. return pbmi;
  579. }
  580. /*-----------------------------------------------------------------------------------
  581. DibCopy: 从一个己经存在的DIB Section去创建一个新的DIB Section(注意:可以会交换
  582. 宽度与高度)
  583. -----------------------------------------------------------------------------------*/
  584. HDIB DibCopy(HDIB hdibSrc, BOOL fRotate)
  585. {
  586. BITMAPINFO* pbmi;
  587. BYTE *pBitsSrc, *pBitsDst;
  588. HDIB hdibDst;
  589. if (!DibIsValid(hdibSrc))
  590. return NULL;
  591. if (NULL == (pbmi = DibCopyToInfo(hdibSrc)))
  592. return NULL;
  593. if (fRotate)
  594. {
  595. pbmi->bmiHeader.biWidth = DibHeight(hdibSrc);
  596. pbmi->bmiHeader.biHeight = DibWidth(hdibSrc);
  597. }
  598. hdibDst = DibCreateFromInfo(pbmi);
  599. free(pbmi);
  600. if (!fRotate) //不旋转时直接复制像素数据。旋转时,需自行处理
  601. {
  602. pBitsSrc = DibBitsPtr(hdibSrc);
  603. pBitsDst = DibBitsPtr(hdibDst);
  604. CopyMemory(pBitsDst, pBitsSrc, DibBitsSize(hdibSrc));
  605. }
  606. return hdibDst;
  607. }
  608. /*-----------------------------------------------------------------------------------
  609. DibCopyToPackedDib:
  610. 通常用于保存DIBs或将DIBs传输到剪贴板。当传输到剪贴板时,第2个参数必须设为TRUE,以便
  611. 分配一个全局共享内存
  612. -----------------------------------------------------------------------------------*/
  613. BITMAPINFO* DibCopyToPackedDib(HDIB hdib, BOOL fUsedGlobal)
  614. {
  615. BITMAPINFO* pPackedDib;
  616. DWORD dwDibSize;
  617. HGLOBAL hGlobal = NULL;
  618. PDIBSTRUCT pdib = hdib;
  619. RGBQUAD* prgb;
  620. BYTE* pBits;
  621. int iNumColors;
  622. HDC hdcMem;
  623. if (!DibIsValid(hdib))
  624. return NULL;
  625. //为紧凑型DIB分配内存
  626. dwDibSize = DibTotalSize(hdib);
  627.  
  628. if (fUsedGlobal)
  629. {
  630. hGlobal = GlobalAlloc(GHND | GMEM_SHARE, dwDibSize);
  631. pPackedDib = GlobalLock(hGlobal);
  632. } else
  633. {
  634. pPackedDib = malloc(dwDibSize);
  635. }
  636.  
  637. if (NULL == pPackedDib)
  638. return NULL;
  639. //复制信息头
  640. CopyMemory(pPackedDib, &pdib->ds.dsBmih, sizeof(BITMAPINFOHEADER));
  641.  
  642. prgb = (RGBQUAD*)((BYTE*)pPackedDib + sizeof(BITMAPINFOHEADER));
  643.  
  644. //复制可能的颜色遮罩
  645. if (pdib->ds.dsBmih.biCompression == BI_BITFIELDS)
  646. {
  647. CopyMemory(prgb, pdib->ds.dsBitfields, * sizeof(DWORD));
  648. prgb = (RGBQUAD*)((BYTE*)prgb + * sizeof(DWORD));
  649. }
  650. //复制颜色表
  651. if (iNumColors = DibNumColors(hdib))
  652. {
  653. hdcMem = CreateCompatibleDC(NULL);
  654. SelectObject(hdcMem, pdib->hBitmap);
  655. GetDIBColorTable(hdcMem, , iNumColors, prgb);
  656. DeleteDC(hdcMem);
  657. }
  658.  
  659. //复制像素数据
  660. pBits = (BYTE*)(prgb + iNumColors);
  661. CopyMemory(pBits, pdib->pBits, DibBitsSize(hdib));
  662. //如果最后一个参数是TRUE,解锁全局内存块,并将全局句块转化为指针返回
  663. if (fUsedGlobal)
  664. {
  665. GlobalUnlock(hGlobal);
  666. pPackedDib = (BITMAPINFO*)hGlobal;
  667. }
  668. return pPackedDib;
  669. }
  670. /*-----------------------------------------------------------------------------------
  671. DibCopyFromPackedDib:通常用于从剪贴板中粘贴DIBs
  672. -----------------------------------------------------------------------------------*/
  673. HDIB DibCopyFromPackedDib(BITMAPINFO* pPackedDib)
  674. {
  675. BYTE* pBits;
  676. DWORD dwInfoSize, dwMaskSize, dwColorSize;
  677. int iBitCount;
  678. PDIBSTRUCT pdib;
  679. //获取信息头类型,并做有效性验证
  680. dwInfoSize = pPackedDib->bmiHeader.biSize;
  681. if (dwInfoSize != sizeof(BITMAPCOREHEADER) &&
  682. dwInfoSize != sizeof(BITMAPINFOHEADER) &&
  683. dwInfoSize != sizeof(BITMAPV4HEADER) &&
  684. dwInfoSize != sizeof(BITMAPV5HEADER))
  685. {
  686. return NULL;
  687. }
  688. //获取可能的颜色遮罩的大小
  689. if (dwInfoSize == sizeof(BITMAPINFOHEADER) &&
  690. pPackedDib->bmiHeader.biCompression == BI_BITFIELDS)
  691. {
  692. dwMaskSize = * sizeof(DWORD);
  693. } else
  694. {
  695. dwMaskSize = ;
  696. }
  697. //获取颜色表的大小
  698. if (dwInfoSize == sizeof(BITMAPCOREHEADER))
  699. {
  700. iBitCount = ((BITMAPCOREHEADER*)pPackedDib)->bcBitCount;
  701. if (iBitCount <= )
  702. {
  703. dwColorSize = ( << (iBitCount))*sizeof(RGBTRIPLE);
  704. } else
  705. dwColorSize = ;
  706. } else //所有非OS/2的DIBs
  707. {
  708. if (pPackedDib->bmiHeader.biClrUsed >)
  709. {
  710. dwColorSize = pPackedDib->bmiHeader.biClrUsed*sizeof(RGBQUAD);
  711. } else if (pPackedDib->bmiHeader.biBitCount <= )
  712. {
  713. dwColorSize = ( << pPackedDib->bmiHeader.biBitCount)*sizeof(RGBQUAD);
  714. } else
  715. {
  716. dwColorSize = ;
  717. }
  718. }
  719. //最后,获得pPackedDIB像素位的指针
  720. pBits = (BYTE*)pPackedDib + dwInfoSize + dwMaskSize + dwColorSize;
  721. //创建HDIB
  722. pdib = DibCreateFromInfo(pPackedDib);
  723. //复制像素位数据
  724. CopyMemory(pdib->pBits, pBits, DibBitsSize(pdib));
  725. return pdib;
  726. }
  727. /*----------------------------------------------------------------------------------
  728. DibFileLoad:从DIB文件中创建DIB Section
  729. -----------------------------------------------------------------------------------*/
  730. HDIB DibFileLoad(const TCHAR* szFileName)
  731. {
  732. HANDLE hFile;
  733. BITMAPFILEHEADER bmfh;
  734. BITMAPINFO* pbmi;
  735. BOOL bSuccess;
  736. DWORD dwInfoSize, dwBytesRead, dwBitsSize;
  737. HDIB hDib;
  738. //打开文件(设为可读可写)
  739. hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
  740. OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  741. if (hFile == INVALID_HANDLE_VALUE)
  742. return NULL;
  743. //读取文件头信息
  744. bSuccess = ReadFile(hFile, &bmfh, sizeof(BITMAPFILEHEADER), &dwBytesRead, NULL);
  745. if (!bSuccess || (dwBytesRead != sizeof(BITMAPFILEHEADER))
  746. || (bmfh.bfType != *(WORD*)"BM"))
  747. {
  748. CloseHandle(hFile);
  749. return NULL;
  750. }
  751. //分配信息头大小,并读入数据
  752. dwInfoSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER);
  753. pbmi = malloc(dwInfoSize);
  754. if (NULL == pbmi)
  755. {
  756. CloseHandle(hFile);
  757. return NULL;
  758. }
  759. bSuccess = ReadFile(hFile, pbmi, dwInfoSize, &dwBytesRead, NULL);
  760. if (!bSuccess || (dwBytesRead != dwInfoSize))
  761. {
  762. CloseHandle(hFile);
  763. free(pbmi);
  764. return NULL;
  765. }
  766. //根据BITMAPINFO结构体来创建DIB
  767. hDib = DibCreateFromInfo(pbmi);
  768. free(pbmi);
  769. if (NULL == hDib)
  770. {
  771. CloseHandle(hFile);
  772. return NULL;
  773. }
  774. //读取像素位数据,放到DIBSTRUCT结构中pBits字段指向的空间中去
  775. dwBitsSize = bmfh.bfSize - bmfh.bfOffBits;
  776. bSuccess = ReadFile(hFile, ((PDIBSTRUCT)hDib)->pBits, dwBitsSize, &dwBytesRead, NULL);
  777. CloseHandle(hFile);
  778. if (!bSuccess || (dwBytesRead != dwBitsSize))
  779. {
  780. DibDelete(hDib);
  781. return NULL;
  782. }
  783. return hDib;
  784. }
  785. /*----------------------------------------------------------------------------------
  786. DibFileSave:将DIB Section位图保存到文件中
  787. -----------------------------------------------------------------------------------*/
  788. BOOL DibFileSave(HDIB hdib, const TCHAR* szFileName)
  789. {
  790. BITMAPFILEHEADER bmfh;
  791. BITMAPINFO* pbmi;
  792. BOOL bSuccess;
  793. DWORD dwTotalSize, dwBytesWritten;
  794. HANDLE hFile;
  795. hFile = CreateFile(szFileName, GENERIC_WRITE, , NULL,
  796. CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  797. if (INVALID_HANDLE_VALUE == hFile)
  798. return FALSE;
  799. dwTotalSize = DibTotalSize(hdib);
  800. bmfh.bfType = *(WORD*)"BM";
  801. bmfh.bfSize = sizeof(BITMAPFILEHEADER) + dwTotalSize;
  802. bmfh.bfReserved1 = ;
  803. bmfh.bfReserved2 = ;
  804. bmfh.bfOffBits = bmfh.bfSize - DibBitsSize(hdib);
  805. //写入BITMAPFILEHEADER
  806. bSuccess = WriteFile(hFile, &bmfh, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
  807. if (!bSuccess || (dwBytesWritten != sizeof(BITMAPFILEHEADER)))
  808. {
  809. CloseHandle(hFile);
  810. DeleteFile(szFileName);
  811. return FALSE;
  812. }
  813. //获取整个紧凑型DIB格式
  814. pbmi = DibCopyToPackedDib(hdib, FALSE);
  815. if (NULL == pbmi)
  816. {
  817. CloseHandle(hFile);
  818. DeleteFile(szFileName);
  819. return FALSE;
  820. }
  821. //写入pbmi指定的整个紧凑型DIB
  822. bSuccess = WriteFile(hFile, pbmi, dwTotalSize, &dwBytesWritten, NULL);
  823. CloseHandle(hFile);
  824. free(pbmi);
  825. if (!bSuccess || (dwBytesWritten != dwTotalSize))
  826. {
  827. DeleteFile(szFileName);
  828. return FALSE;
  829. }
  830. return TRUE;
  831. }
  832. /*----------------------------------------------------------------------------------
  833. DibCopyToDdb:更高效的屏幕显示
  834. -----------------------------------------------------------------------------------*/
  835. HBITMAP DibCopyToDdb(HDIB hdib, HWND hwnd, HPALETTE hPalette)
  836. {
  837. HBITMAP hBitmap;
  838. BITMAPINFO* pbmi;
  839. HDC hdc;
  840.  
  841. if (!DibIsValid(hdib))
  842. return NULL;
  843. if (NULL == (pbmi = DibCopyToInfo(hdib)))
  844. return NULL;
  845. hdc = GetDC(hwnd);
  846. if (hPalette)
  847. {
  848. SelectPalette(hdc, hPalette, FALSE);
  849. RealizePalette(hdc);
  850. }
  851. hBitmap = CreateDIBitmap(hdc, DibInfoHeaderPtr(hdib), CBM_INIT,
  852. DibBitsPtr(hdib), pbmi, DIB_RGB_COLORS);
  853. ReleaseDC(hwnd, hdc);
  854. free(pbmi);
  855. return hBitmap;
  856. }
  857. /*----------------------------------------------------------------------------------
  858. DibFlipHorizontal:调用没有优化的DibSetPixel和DibGetPixel
  859. ----------------------------------------------------------------------------------*/
  860. HDIB DibFlipHorizontal(HDIB hdibSrc)
  861. {
  862. HDIB hdibDst;
  863. int cx, cy, x, y;
  864. if (!DibIsAddressable(hdibSrc))
  865. return NULL;
  866. if (NULL == (hdibDst = DibCopy(hdibSrc, FALSE)))
  867. return NULL;
  868. cx = DibWidth(hdibSrc);
  869. cy = DibHeight(hdibSrc);
  870. for (x = ; x < cx; x++)
  871. for (y = ; y < cy; y++)
  872. {
  873. DibSetPixel(hdibDst, x, cy - - y, DibGetPixel(hdibSrc, x, y));
  874. }
  875.  
  876. return hdibDst;
  877. }
  878. /*----------------------------------------------------------------------------------
  879. DibRotateRight:调用优化过的DibSetPixelx和DibGetPixelx
  880. ----------------------------------------------------------------------------------*/
  881. HDIB DibRotateRight(HDIB hdibSrc)
  882. {
  883. HDIB hdibDst;
  884. int cx, cy, x, y;
  885. if (!DibIsAddressable(hdibSrc))
  886. return NULL;
  887. if (NULL == (hdibDst = DibCopy(hdibSrc, TRUE)))
  888. return NULL;
  889. cx = DibWidth(hdibSrc);
  890. cy = DibHeight(hdibSrc);
  891. switch (DibBitCount(hdibSrc))
  892. {
  893. case :
  894. for (x = ; x < cx; x++)
  895. for (y = ; y < cy; y++)
  896. {
  897. DibSetPixel1(hdibDst, cy - - y, x, DibGetPixel1(hdibSrc, x, y)); //坐标旋转
  898. }
  899. break;
  900. case :
  901. for (x = ; x < cx; x++)
  902. for (y = ; y < cy; y++)
  903. {
  904. DibSetPixel4(hdibDst, cy - - y, x, DibGetPixel4(hdibSrc, x, y));
  905. }
  906. break;
  907. case :
  908. for (x = ; x < cx; x++)
  909. for (y = ; y < cy; y++)
  910. {
  911. DibSetPixel8(hdibDst, cy - - y, x, DibGetPixel8(hdibSrc, x, y));
  912. }
  913. break;
  914. case :
  915. for (x = ; x < cx; x++)
  916. for (y = ; y < cy; y++)
  917. {
  918. DibSetPixel16(hdibDst, cy - - y, x, DibGetPixel16(hdibSrc, x, y));
  919. }
  920. break;
  921. case :
  922. for (x = ; x < cx; x++)
  923. for (y = ; y < cy; y++)
  924. {
  925. DibSetPixel24(hdibDst, cy - - y, x, DibGetPixel24(hdibSrc, x, y));
  926. }
  927. break;
  928. case :
  929. for (x = ; x < cx; x++)
  930. for (y = ; y < cy; y++)
  931. {
  932. DibSetPixel32(hdibDst, cy - - y, x, DibGetPixel32(hdibSrc, x, y));
  933. }
  934. break;
  935. }
  936. return hdibDst;
  937. }

//未完,接下一篇

第16章 调色板管理器_16.4 一个DIB位图库的实现(1)的更多相关文章

  1. 第16章 调色板管理器_16.4 一个DIB位图库的实现(2)

    //接上一篇 //DibPal.h /*----------------------------------------------------------------- DIBPAL.H heade ...

  2. 第15章 上下文管理器和else块

    #<流流畅的Python>第15章 上下文管理器和else块 #15.1 先做这个,再做那个:if语句之外的else块 #else子句不仅能在if语句中使用,还能在for.while和tr ...

  3. 【Ubuntu 16】显示管理器lightdm

    lightdm是一个全新的轻量级的显示管理器,在Ubuntu16.04上面已经使用. 从图形界面进入到命令行界面 systemctl disable lightdm.service 从命令行进入到图形 ...

  4. 流畅的python第十五章上下文管理器和else块学习记录

    with 语句和上下文管理器for.while 和 try 语句的 else 子句 with 语句会设置一个临时的上下文,交给上下文管理器对象控制,并且负责清理上下文.这么做能避免错误并减少样板代码, ...

  5. 第4章 URL管理器和实现方法

    URL管理器:管理待抓取URL集合和已抓取URL集合 -- 防止重复抓取.防止循环抓取 URL需要支持哪些功能: 添加新URL到待爬取集合中.判断待添加URL是否在容器中,判断是否还有待爬取URL,获 ...

  6. 转:OGRE场景管理器介绍

    一个场景代表在虚拟世界中显示的物品.场景可以包括静态几何体(比如地形或者室内),模型(比如树.椅子等),光和摄像机.场景有下面种类.室内场景:可能由走廊.有家具的屋子和挂着装饰品的墙组成.室外场景:可 ...

  7. 【java】浅析java组件中的布局管理器

    这篇博文笔者介绍一下java组件中,常用的布局管理器.java组件中的布局方式有好几十种,所有的这些布局管理器都实现了java.awt.LayoutManager接口.接下来笔者介绍一下常用的5种布局 ...

  8. yum 软件管理器

    yum软件管理器 yum是一个强大的软件包管理器,能够自动解决安装时rpm包之间的依赖关系. 一.使用yum管理软件包 1.使用命令 yum help 查看使用方法 [root@majinhai ~] ...

  9. [Qt Creator 快速入门] 第4章 布局管理

    第3章讲述了一些窗口部件,当时往界面上拖放部件时都是随意放置的,这对于学习部件的使用没有太大的影响,但是,对于一个完善的软件,布局管理却是必不可少的. 无论是想要界面中部件有一个很整齐的排列,还是想要 ...

随机推荐

  1. javascript --- Function模式

    回调函数 在javascript中,当一个函数A作为另外一个函数B的其中一个参数时,则称A函数为回调函数,即A可以在函数B的运行周期内执行(开始,中间,结束). 举例来说,有一个函数用于生成node. ...

  2. 读jQuery源码 - Deferred

    Deferred首次出现在jQuery 1.5中,在jQuery 1.8之后被改写,它的出现抹平了javascript中的大量回调产生的金字塔,提供了异步编程的能力,它主要服役于jQuery.ajax ...

  3. linux系统免密码登陆

    有两台机器,系统都是CentOS6.5,IP分别为192.168.2.150,192.168.2.151.现在150需要SSH免密码登陆151. 在150上面执行命令,当前登录用户是root: # s ...

  4. [原] SharePoint 2010 WebPart与Google地图系列 一:创建显示地图的WebPart

    摘要: 作为信息化先驱的产品SharePoint 2010竟然对GIS相关技术支持如此有限,试问现在哪个企业没有大量的项目需要结合Google地图来进行开发,单纯地从Google Javascript ...

  5. Warning: Attempt to present on whose view is not in the window hierarchy!

    当我想从一个VC跳转到另一个VC的时候,一般会用 - (void)presentViewController:(UIViewController *)viewControllerToPresent a ...

  6. 体验最火的敏捷——SCRUM(厦门,2014.1.4)

    1.概述SCRUM是当前最火的一种敏捷开发方法,有用户故事.冲刺.燃尽图等很多很酷的玩法,有牛B的产品负责人.SCRUM Master,有超强的自组织团队.本沙龙将为您展现当前最火最酷的敏捷开发方法! ...

  7. WPF学习之路(十二)控件(Range控件)

    ProgressBar 进度条,主要属性:Minimum\Maximun\Value, IsIndeterminate为True时,进度条会循环运转 <Grid> <Grid.Row ...

  8. TypeId和IidManager关系

    IidInformation结构 数据类型 名字 string name TypeId::hash_t hash uint16_t parent string groupName size_t siz ...

  9. 按要求编写Java应用程序。 (1)建立一个名叫Cat的类: 属性:姓名、毛色、年龄 行为:显示姓名、喊叫 (2)编写主类: 创建一个对象猫,姓名为“妮妮”,毛色为“灰色”,年龄为2岁,在屏幕上输 出该对象的毛色和年龄,让该对象调用显示姓名和喊叫两个方法。

    package zuoye; public class Cat { String name="妮妮"; String color="灰色"; int age=1 ...

  10. jquery最常用的几个方法。

    jquery使用手册:http://www.eduyo.com/doc/jquery/cheatsheet.html addClass 样式: <style> .textRed { col ...