第16章 调色板管理器_16.4 一个DIB位图库的实现(1)
字段 |
含义 |
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主程序
- /*------------------------------------------------------------
- DIBBLE.C -- Bitmap and Palette Program
- (c) Charles Petzold, 1998
- ------------------------------------------------------------*/
- #include <windows.h>
- #include "resource.h"
- #include "DibHelp.h"
- #include "DibConv.h"
- #include "DibPal.h"
- #define WM_USER_SETSCROLLS (WM_USER + 1)
- #define WM_USER_DELETEDIB (WM_USER + 2)
- #define WM_USER_DELETEPAL (WM_USER + 3)
- #define WM_USER_CREATEPAL (WM_USER + 4)
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
- static TCHAR szAppName[] = TEXT("Dibble");
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
- PSTR szCmdLine, int iCmdShow)
- {
- HWND hwnd;
- MSG msg;
- WNDCLASSEX wndclass;
- HACCEL hAccel;
- wndclass.style = CS_HREDRAW | CS_VREDRAW;
- wndclass.cbSize = sizeof(WNDCLASSEX);
- wndclass.lpfnWndProc = WndProc;
- wndclass.cbClsExtra = ;
- wndclass.cbWndExtra = ;
- wndclass.hInstance = hInstance;
- wndclass.hIcon = LoadIcon(hInstance, szAppName);
- wndclass.hIconSm = LoadIcon(hInstance, szAppName);
- wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
- wndclass.lpszMenuName = szAppName;
- wndclass.lpszClassName = szAppName;
- if (!RegisterClassEx(&wndclass))
- {
- MessageBox(NULL, TEXT("This program requires Windows NT!"),
- szAppName, MB_ICONERROR);
- return ;
- }
- hwnd = CreateWindow(szAppName, // window class name
- szAppName, // window caption
- WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL, // window style
- CW_USEDEFAULT, // initial x position
- CW_USEDEFAULT, // initial y position
- CW_USEDEFAULT, // initial x size
- CW_USEDEFAULT, // initial y size
- NULL, // parent window handle
- NULL, // window menu handle
- hInstance, // program instance handle
- NULL); // creation parameters
- ShowWindow(hwnd, iCmdShow);
- UpdateWindow(hwnd);
- hAccel = LoadAccelerators(hInstance, szAppName);
- while (GetMessage(&msg, NULL, , ))
- {
- if (!TranslateAccelerator(hwnd, hAccel, &msg))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- return msg.wParam;
- }
- /*-------------------------------------------------------------------------------
- DisplayDib:根据菜单项的选择来显示(打印)DIB的实际大小图像或缩放的图像
- --------------------------------------------------------------------------------*/
- int DisplayDib(HDC hdc, HBITMAP hBitmap, int x, int y,
- int cxClient, int cyClient,
- WORD wShow, BOOL fHalftonePalette)
- {
- BITMAP bitmap;
- HDC hdcMem;
- int cxBitmap, cyBitmap, iReturn;
- GetObject(hBitmap, sizeof(BITMAP), &bitmap);
- cxBitmap = bitmap.bmWidth;
- cyBitmap = bitmap.bmHeight;
- SaveDC(hdc);
- if (fHalftonePalette)
- SetStretchBltMode(hdc, HALFTONE);
- else
- SetStretchBltMode(hdc, COLORONCOLOR);
- hdcMem = CreateCompatibleDC(hdc);
- SelectObject(hdcMem, hBitmap);
- switch (wShow)
- {
- case IDM_SHOW_NORMAL:
- if (fHalftonePalette)
- {
- iReturn = StretchBlt(hdc, , ,
- min(cxClient, cxBitmap - x),
- min(cyClient, cyBitmap - y),
- hdcMem, x, y,
- min(cxClient, cxBitmap - x),
- min(cyClient, cyBitmap - y),
- SRCCOPY);
- } else
- {
- iReturn = BitBlt(hdc, , ,
- min(cxClient, cxBitmap - x),
- min(cyClient, cyBitmap - y),
- hdcMem, x, y, SRCCOPY);
- }
- break;
- case IDM_SHOW_CENTER:
- if (fHalftonePalette)
- {
- iReturn = StretchBlt(hdc, (cxClient - cxBitmap) / , (cyClient - cyBitmap) / ,
- cxBitmap, cyBitmap,
- hdcMem, , ,
- cxBitmap, cyBitmap,
- SRCCOPY);
- } else
- {
- iReturn = BitBlt(hdc, (cxClient - cxBitmap) / , (cyClient - cyBitmap) / ,
- cxBitmap, cyBitmap,
- hdcMem, , , SRCCOPY);
- }
- break;
- case IDM_SHOW_STRETCH:
- iReturn = StretchBlt(hdc, , ,
- cxClient, cyClient,
- hdcMem, , ,
- cxBitmap, cyBitmap,
- SRCCOPY);
- break;
- case IDM_SHOW_ISOSTRETCH:
- SetMapMode(hdc, MM_ISOTROPIC);
- SetWindowExtEx(hdc, cxBitmap, cyBitmap, NULL);
- SetViewportExtEx(hdc, cxClient, cyClient, NULL);
- SetWindowOrgEx(hdc, cxBitmap / , cyBitmap / , NULL);
- SetViewportOrgEx(hdc, cxClient / , cyClient / , NULL);
- //iReturn = StretchBlt(hdc, 0, 0,
- // cxBitmap, cyBitmap,
- // hdcMem, 0, 0,
- // cxBitmap, cyBitmap,
- // SRCCOPY);
- iReturn = BitBlt(hdc, , ,
- cxBitmap, cyBitmap,
- hdcMem, , ,
- SRCCOPY);
- break;
- }
- DeleteDC(hdcMem);
- RestoreDC(hdc, -);
- return iReturn;
- }
- /*-------------------------------------------------------------------------------
- PaletteMenu:设置“Palette”各菜单项的Check属性
- --------------------------------------------------------------------------------*/
- void PaletteMenu(HMENU hMenu, WORD wItemNew)
- {
- static WORD wItem = IDM_PAL_NONE;
- CheckMenuItem(hMenu, wItem, MF_UNCHECKED);
- wItem = wItemNew;
- CheckMenuItem(hMenu, wItem, MF_CHECKED);
- }
- LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- static OPENFILENAME ofn;
- static TCHAR szFileName[MAX_PATH], szTitleName[MAX_PATH];
- static TCHAR szFilter[] = TEXT("Bitmap Files (*.BMP)\0*.bmp\0")
- TEXT("All Files (*.*)\0*.*\0\0");
- static TCHAR* szCompression[] = {
- TEXT("BI_RGB"), TEXT("BI_RLE8"),
- TEXT("BI_RLE4"), TEXT("BI_BITFIELDS"),
- TEXT("Unknown") };
- static HDIB hdib;
- static HPALETTE hPalette;
- static HBITMAP hBitmap;
- static BOOL fHalftonePalette;
- static HMENU hMenu;
- BOOL fSuccess;
- static int cxClient, cyClient, iHscroll, iVscroll;
- static WORD wShow = IDM_SHOW_NORMAL;
- static PRINTDLG printdlg = { sizeof(PRINTDLG) };
- static DOCINFO di = { sizeof(DOCINFO), TEXT("Dibble:Printing") };
- int cxPage, cyPage;
- HDC hdc, hdcPrn;
- HGLOBAL hGlobal;
- BYTE* pGlobal;
- HDIB hdibNew;
- PAINTSTRUCT ps;
- SCROLLINFO si;
- int iEnable, iConvert = ;
- TCHAR szBuffer[];
- switch (message)
- {
- case WM_CREATE:
- //将菜单句柄保存在静态变量hMenu中
- hMenu = GetMenu(hwnd);
- //初始化打开文件对话框
- memset(&ofn, , sizeof(OPENFILENAME));
- ofn.lStructSize = sizeof(OPENFILENAME);
- ofn.hwndOwner = hwnd;
- ofn.lpstrFilter = szFilter;
- ofn.lpstrFile = szFileName;
- ofn.nMaxFile = MAX_PATH;
- ofn.lpstrFileTitle = szTitleName;
- ofn.nMaxFileTitle = MAX_PATH;
- ofn.Flags = OFN_OVERWRITEPROMPT;
- ofn.lpstrDefExt = TEXT("bmp");
- return ;
- case WM_SIZE:
- cxClient = LOWORD(lParam);
- cyClient = HIWORD(lParam);
- wParam = FALSE; //贯穿功能,继续执行下面的代码
- //用户自定义消息,设置滚动条,如果显示模式是正常模式,则隐藏滚动条。如果
- //wParam==TRUE,则复位滚动条的位置
- case WM_USER_SETSCROLLS:
- if (hdib == NULL || wShow != IDM_SHOW_NORMAL)
- {
- si.cbSize = sizeof(SCROLLINFO);
- si.fMask = SIF_RANGE;
- si.nMin = ;
- si.nMax = ;
- SetScrollInfo(hwnd, SB_VERT, &si, TRUE); //隐藏
- SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
- } else
- {
- //垂直滚动条
- si.cbSize = sizeof(SCROLLINFO);
- si.fMask = SIF_ALL;
- GetScrollInfo(hwnd, SB_VERT, &si);
- si.nMin = ;
- si.nMax = DibHeight(hdib);
- si.nPage = cyClient;
- if ((BOOL)wParam) //恢复到0的默认位置
- si.nPos = ;
- SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
- GetScrollInfo(hwnd, SB_VERT, &si);
- iVscroll = si.nPos;
- //水平滚动条
- GetScrollInfo(hwnd, SB_HORZ, &si);
- si.nMin = ;
- si.nMax = DibWidth(hdib);
- si.nPage = cxClient;
- if ((BOOL)wParam) //恢复到0的默认位置
- si.nPos = ;
- SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
- GetScrollInfo(hwnd, SB_HORZ, &si);
- iHscroll = si.nPos;
- }
- return ;
- case WM_VSCROLL:
- si.cbSize = sizeof(SCROLLINFO);
- si.fMask = SIF_ALL;
- GetScrollInfo(hwnd, SB_VERT, &si);
- iVscroll = si.nPos;
- switch (LOWORD(wParam))
- {
- case SB_LINEUP: si.nPos -= ; break;
- case SB_LINEDOWN: si.nPos += ; break;
- case SB_PAGEUP: si.nPage -= si.nPage; break;
- case SB_PAGEDOWN: si.nPage += si.nPage; break;
- case SB_THUMBTRACK: si.nPos = si.nTrackPos; break;
- default: break;
- }
- si.fMask = SIF_POS;
- SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
- GetScrollInfo(hwnd, SB_VERT, &si);
- if (si.nPos != iVscroll)
- {
- ScrollWindow(hwnd, , iVscroll - si.nPos, NULL, NULL);
- iVscroll = si.nPos;
- UpdateWindow(hwnd); //立即更新窗口,这行可以注释掉
- }
- return ;
- case WM_HSCROLL:
- si.cbSize = sizeof(SCROLLINFO);
- si.fMask = SIF_ALL;
- GetScrollInfo(hwnd, SB_HORZ, &si);
- iHscroll = si.nPos;
- switch (LOWORD(wParam))
- {
- case SB_LINELEFT: si.nPos -= ; break;
- case SB_LINERIGHT: si.nPos += ; break;
- case SB_PAGELEFT: si.nPage -= si.nPage; break;
- case SB_PAGERIGHT: si.nPage += si.nPage; break;
- case SB_THUMBTRACK: si.nPos = si.nTrackPos; break;
- default: break;
- }
- si.fMask = SIF_POS;
- SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
- GetScrollInfo(hwnd, SB_HORZ, &si);
- if (si.nPos != iHscroll)
- {
- ScrollWindow(hwnd, iHscroll - si.nPos, , NULL, NULL);
- iHscroll = si.nPos;
- UpdateWindow(hwnd); //立即更新窗口,这行可以注释掉
- }
- return ;
- case WM_INITMENUPOPUP:
- if (hdib)
- iEnable = MF_ENABLED;
- else
- iEnable = MF_GRAYED;
- EnableMenuItem(hMenu, IDM_FILE_SAVE, iEnable);
- EnableMenuItem(hMenu, IDM_FILE_PRINT, iEnable);
- EnableMenuItem(hMenu, IDM_FILE_PROPERTIES, iEnable);
- EnableMenuItem(hMenu, IDM_EDIT_CUT, iEnable);
- EnableMenuItem(hMenu, IDM_EDIT_COPY, iEnable);
- EnableMenuItem(hMenu, IDM_EDIT_DELETE, iEnable);
- if (DibIsAddressable(hdib))
- iEnable = MF_ENABLED;
- else
- iEnable = MF_GRAYED;
- EnableMenuItem(hMenu, IDM_EDIT_ROTATE, iEnable);
- EnableMenuItem(hMenu, IDM_EDIT_FLIP, iEnable);
- EnableMenuItem(hMenu, IDM_CONVERT_01, iEnable);
- EnableMenuItem(hMenu, IDM_CONVERT_04, iEnable);
- EnableMenuItem(hMenu, IDM_CONVERT_08, iEnable);
- EnableMenuItem(hMenu, IDM_CONVERT_16, iEnable);
- EnableMenuItem(hMenu, IDM_CONVERT_24, iEnable);
- EnableMenuItem(hMenu, IDM_CONVERT_32, iEnable);
- switch (DibBitCount(hdib))
- {
- case : EnableMenuItem(hMenu, IDM_CONVERT_01, MF_GRAYED); break;
- case : EnableMenuItem(hMenu, IDM_CONVERT_04, MF_GRAYED); break;
- case : EnableMenuItem(hMenu, IDM_CONVERT_08, MF_GRAYED); break;
- case : EnableMenuItem(hMenu, IDM_CONVERT_16, MF_GRAYED); break;
- case : EnableMenuItem(hMenu, IDM_CONVERT_24, MF_GRAYED); break;
- case : EnableMenuItem(hMenu, IDM_CONVERT_32, MF_GRAYED); break;
- }
- if (hdib && DibColorSize(hdib) > )
- iEnable = MF_ENABLED;
- else
- iEnable = MF_GRAYED;
- EnableMenuItem(hMenu, IDM_PAL_DIBTABLE, iEnable);
- if (DibIsAddressable(hdib) && DibBitCount(hdib)>)
- iEnable = MF_ENABLED;
- else
- iEnable = MF_GRAYED;
- EnableMenuItem(hMenu, IDM_PAL_OPT_POP4, iEnable);
- EnableMenuItem(hMenu, IDM_PAL_OPT_POP5, iEnable);
- EnableMenuItem(hMenu, IDM_PAL_OPT_POP6, iEnable);
- EnableMenuItem(hMenu, IDM_PAL_OPT_MEDCUT, iEnable);
- EnableMenuItem(hMenu, IDM_EDIT_PASTE, IsClipboardFormatAvailable(CF_DIB) ? MF_ENABLED : MF_GRAYED);
- return ;
- case WM_COMMAND:
- switch (LOWORD(wParam))
- {
- case IDM_FILE_OPEN:
- //显示“打开文件”对话框
- if (!GetOpenFileName(&ofn))
- return ;
- //如果DIB和调色板己经存在,则删除它们
- SendMessage(hwnd, WM_USER_DELETEDIB, , );
- //加载DIB文件到内存
- SetCursor(LoadCursor(NULL, IDC_WAIT));
- ShowCursor(TRUE);
- hdib = DibFileLoad(szFileName);
- SetCursor(LoadCursor(NULL, IDC_ARROW));
- ShowCursor(FALSE);
- //重置滚动条
- SendMessage(hwnd, WM_USER_SETSCROLLS, TRUE, );
- //创建调色板和DDB
- SendMessage(hwnd, WM_USER_CREATEPAL, TRUE, ); //根据调色板,创建DDB——hBitmap
- if (!hdib)
- {
- MessageBox(hwnd, TEXT("Cannot load DIB file!"),
- szAppName, MB_OK | MB_ICONEXCLAMATION);
- }
- InvalidateRect(hwnd, NULL, TRUE);
- return ;
- case IDM_FILE_SAVE:
- //打开“保存”对话框
- if (!GetSaveFileName(&ofn))
- return ;
- //将DIB保存到文件中
- SetCursor(LoadCursor(NULL, IDC_WAIT));
- ShowCursor(TRUE);
- fSuccess = DibFileSave(hdib, szFileName);
- SetCursor(LoadCursor(NULL, IDC_ARROW));
- ShowCursor(FALSE);
- if (!fSuccess)
- {
- MessageBox(hwnd, TEXT("Cannot Save DIB file!"),
- szAppName, MB_OK | MB_ICONEXCLAMATION);
- }
- return ;
- case IDM_FILE_PRINT:
- if (!hdib)
- return ;
- //获得打印机DC
- printdlg.Flags = PD_RETURNDC | PD_NOPAGENUMS | PD_NOSELECTION;
- if (!PrintDlg(&printdlg))
- return ;
- if (NULL == (hdcPrn = printdlg.hDC))
- {
- MessageBox(hwnd, TEXT("Cannot obtain Printer DC"), szAppName, MB_ICONEXCLAMATION | MB_OK);
- return ;
- }
- //检查打印机是否支持打印位图
- if (!(RC_BITBLT & GetDeviceCaps(hdcPrn, RASTERCAPS)))
- {
- DeleteDC(hdcPrn);
- MessageBox(hwnd, TEXT("Printer cannot print bitmaps"), szAppName, MB_ICONEXCLAMATION | MB_OK);
- return ;
- }
- //获取打机印的可打印区域
- cxPage = GetDeviceCaps(hdcPrn, HORZRES);
- cyPage = GetDeviceCaps(hdcPrn, VERTRES);
- fSuccess = FALSE;
- //将DIB发送到打印机
- SetCursor(LoadCursor(NULL, IDC_WAIT));
- ShowCursor(TRUE);
- if ((StartDoc(hdcPrn, &di) > ) && (StartPage(hdcPrn) > ))
- {
- DisplayDib(hdcPrn, DibBitmapHandle(hdib), , , cxPage, cyPage, wShow, FALSE);
- if (EndPage(hdcPrn) > )
- {
- fSuccess = TRUE;
- EndDoc(hdcPrn);
- }
- }
- ShowCursor(FALSE);
- SetCursor(LoadCursor(NULL, IDC_ARROW));
- DeleteDC(hdcPrn);
- if (!fSuccess)
- MessageBox(hwnd, TEXT("Cannot print bitmaps"),
- szAppName, MB_ICONEXCLAMATION | MB_OK);
- return ;
- case IDM_FILE_PROPERTIES:
- if (!hdib)
- return ;
- wsprintf(szBuffer, TEXT("Pixel width:\t%i\n") //%i与%d一样的
- TEXT("Pixel Height:\t%i\n")
- TEXT("Bits per pixel:\t%i\n")
- TEXT("Number of colors:\t%i\n")
- TEXT("Compression:\t%s\n"),
- DibWidth(hdib), DibHeight(hdib),
- DibBitCount(hdib), DibNumColors(hdib),
- szCompression[min(, DibCompression(hdib))]);
- MessageBox(hwnd, szBuffer, szAppName, MB_ICONEXCLAMATION | MB_OK);
- return ;
- case IDM_APP_EXIT:
- SendMessage(hwnd, WM_CLOSE, , );
- return ;
- case IDM_EDIT_COPY:
- case IDM_EDIT_CUT:
- if (!(hGlobal = DibCopyToPackedDib(hdib, TRUE)))
- return ;
- OpenClipboard(hwnd);
- EmptyClipboard();
- SetClipboardData(CF_DIB, hGlobal);
- CloseClipboard();
- if (LOWORD(wParam) == IDM_EDIT_COPY)
- return ;
- //剪切时,继续执行下去
- case IDM_EDIT_DELETE:
- SendMessage(hwnd, WM_USER_DELETEDIB, , );
- InvalidateRect(hwnd, NULL, TRUE);
- return ;
- case IDM_EDIT_PASTE:
- OpenClipboard(hwnd);
- hGlobal = GetClipboardData(CF_DIB);
- pGlobal = GlobalLock(hGlobal);
- //如果己经存在DIB位图和调色板,则删除它们
- if (pGlobal)
- {
- SendMessage(hwnd, WM_USER_DELETEDIB, , );
- hdib = DibCopyFromPackedDib((BITMAPINFO*)pGlobal);
- SendMessage(hwnd, WM_USER_CREATEPAL, TRUE, );
- }
- GlobalUnlock(hGlobal);
- CloseClipboard();
- //重置滚动条
- SendMessage(hwnd, WM_USER_SETSCROLLS, TRUE, );
- InvalidateRect(hwnd, NULL, TRUE);
- return ;
- case IDM_EDIT_ROTATE:
- if (hdibNew = DibRotateRight(hdib))
- {
- DibDelete(hdib);
- DeleteObject(hBitmap);
- hdib = hdibNew;
- hBitmap = DibCopyToDdb(hdib, hwnd, hPalette);
- SendMessage(hwnd, WM_USER_SETSCROLLS, TRUE, );
- InvalidateRect(hwnd, NULL, TRUE);
- } else
- {
- MessageBox(hwnd, TEXT("Not enough memory"),
- szAppName, MB_OK | MB_ICONEXCLAMATION);
- }
- return ;
- case IDM_EDIT_FLIP:
- if (hdibNew = DibFlipHorizontal(hdib))
- {
- DibDelete(hdib);
- DeleteObject(hBitmap);
- hdib = hdibNew;
- hBitmap = DibCopyToDdb(hdib, hwnd, hPalette);
- InvalidateRect(hwnd, NULL, TRUE);
- } else
- {
- MessageBox(hwnd, TEXT("Not enough memory"),
- szAppName, MB_OK | MB_ICONEXCLAMATION);
- }
- return ;
- case IDM_SHOW_NORMAL:
- case IDM_SHOW_STRETCH:
- case IDM_SHOW_CENTER:
- case IDM_SHOW_ISOSTRETCH:
- CheckMenuItem(hMenu, wShow, MF_UNCHECKED);
- wShow = LOWORD(wParam);
- CheckMenuItem(hMenu, wShow, MF_CHECKED);
- SendMessage(hwnd, WM_USER_SETSCROLLS, TRUE, );
- InvalidateRect(hwnd, NULL, TRUE);
- return ;
- case IDM_CONVERT_32:iConvert += ;
- case IDM_CONVERT_24:iConvert += ;
- case IDM_CONVERT_16:iConvert += ;
- case IDM_CONVERT_08:iConvert += ;
- case IDM_CONVERT_04:iConvert += ;
- case IDM_CONVERT_01:iConvert += ;
- SetCursor(LoadCursor(NULL, IDC_WAIT));
- ShowCursor(TRUE);
- hdibNew = DibConvert(hdib, iConvert);
- ShowCursor(FALSE);
- SetCursor(LoadCursor(NULL, IDC_ARROW));
- if (hdibNew)
- {
- SendMessage(hwnd, WM_USER_DELETEDIB, , );
- hdib = hdibNew;
- SendMessage(hwnd, WM_USER_CREATEPAL, TRUE, );
- InvalidateRect(hwnd, NULL, TRUE);
- } else
- {
- MessageBox(hwnd, TEXT("Not enough memory"),
- szAppName, MB_OK | MB_ICONEXCLAMATION);
- }
- return ;
- case IDM_APP_ABOUT:
- MessageBox(hwnd, TEXT("Dibble (c) Charles Petzold,1998"),
- szAppName, MB_OK | MB_ICONEXCLAMATION);
- return ;
- }
- //其余所有的WM_COMMAND消息都是来自调色板项目。如果删除己经存在的调色板,光标将被
- //设置为沙漏的形状
- SendMessage(hwnd, WM_USER_DELETEPAL, , );
- SetCursor(LoadCursor(NULL, IDC_WAIT));
- ShowCursor(TRUE);
- //提醒,所有的调色板消息都以break结束而不是return,这允许后面进行一些额外的处理
- switch (LOWORD(wParam))
- {
- case IDM_PAL_DIBTABLE:
- hPalette = DibPalDibTable(hdib);
- break;
- case IDM_PAL_HALFTONE:
- hdc = GetDC(hwnd);
- if (hPalette = CreateHalftonePalette(hdc))
- fHalftonePalette = TRUE;
- ReleaseDC(hwnd, hdc);
- break;
- case IDM_PAL_ALLPURPOSE:
- hPalette = DibPalAllPurpose();
- break;
- case IDM_PAL_GRAY2: hPalette = DibPalUniformGrays(); break;
- case IDM_PAL_GRAY3: hPalette = DibPalUniformGrays(); break;
- case IDM_PAL_GRAY4: hPalette = DibPalUniformGrays(); break;
- case IDM_PAL_GRAY8: hPalette = DibPalUniformGrays(); break;
- case IDM_PAL_GRAY16: hPalette = DibPalUniformGrays(); break;
- case IDM_PAL_GRAY32: hPalette = DibPalUniformGrays(); break;
- case IDM_PAL_GRAY64: hPalette = DibPalUniformGrays(); break;
- case IDM_PAL_GRAY128: hPalette = DibPalUniformGrays(); break;
- case IDM_PAL_GRAY256: hPalette = DibPalUniformGrays(); break;
- case IDM_PAL_RGB222: hPalette = DibPalUniformColors(, , ); break;
- case IDM_PAL_RGB333: hPalette = DibPalUniformColors(, , ); break;
- case IDM_PAL_RGB444: hPalette = DibPalUniformColors(, , ); break;
- case IDM_PAL_RGB555: hPalette = DibPalUniformColors(, , ); break;
- case IDM_PAL_RGB666: hPalette = DibPalUniformColors(, , ); break;
- case IDM_PAL_RGB775: hPalette = DibPalUniformColors(, , ); break;
- case IDM_PAL_RGB757: hPalette = DibPalUniformColors(, , ); break;
- case IDM_PAL_RGB577: hPalette = DibPalUniformColors(, , ); break;
- case IDM_PAL_RGB884: hPalette = DibPalUniformColors(, , ); break;
- case IDM_PAL_RGB848: hPalette = DibPalUniformColors(, , ); break;
- case IDM_PAL_RGB488: hPalette = DibPalUniformColors(, , ); break;
- case IDM_PAL_OPT_POP4:
- hPalette = DibPalPopularity(hdib, );
- break;
- case IDM_PAL_OPT_POP5:
- hPalette = DibPalPopularity(hdib, );
- break;
- case IDM_PAL_OPT_POP6:
- hPalette = DibPalPopularity(hdib, );
- break;
- case IDM_PAL_OPT_MEDCUT:
- hPalette = DibPalMedianCut(hdib, );
- break;
- }
- //当处理完菜单中的调色板项目后,光标恢复为箭头的形状,该项被设为Checked,并
- //且刷新客户区
- hBitmap = DibCopyToDdb(hdib, hwnd, hPalette);
- ShowCursor(FALSE);
- SetCursor(LoadCursor(NULL, IDC_ARROW));
- if (hPalette)
- PaletteMenu(hMenu, (LOWORD(wParam)));
- InvalidateRect(hwnd, NULL, TRUE);
- return ; //WM_COMMAND消息处理完毕
- //该消息中删除一个己经存在的DIB,为获取一个新DIB作准备。
- //该消息会被打开、粘贴或其它菜单命令所调用
- case WM_USER_DELETEDIB:
- if (hdib)
- {
- DibDelete(hdib);
- hdib = NULL;
- }
- SendMessage(hwnd, WM_USER_DELETEPAL, , );
- return ;
- //基于一个新DIB创建一个调色板。如果wParam==TRUE,则同时创建DDB
- case WM_USER_CREATEPAL:
- if (hdib)
- {
- hdc = GetDC(hwnd);
- if (!(RC_PALETTE & GetDeviceCaps(hdc, RASTERCAPS))) //不支持调色调
- {
- PaletteMenu(hMenu, IDM_PAL_NONE);
- } else if (hPalette = CreateHalftonePalette(hdc)) //创建半色调调色板
- {
- fHalftonePalette = TRUE;
- PaletteMenu(hMenu, IDM_PAL_HALFTONE);
- }
- ReleaseDC(hwnd, hdc);
- if ((BOOL)wParam)
- hBitmap = DibCopyToDdb(hdib, hwnd, hPalette);
- }
- return ;
- //删除一个己经存在的调色板,为创建新调色板做准备
- case WM_USER_DELETEPAL:
- if (hPalette)
- {
- DeleteObject(hPalette);
- hPalette = NULL;
- fHalftonePalette = FALSE;
- PaletteMenu(hMenu, IDM_PAL_NONE);
- }
- if (hBitmap)
- {
- DeleteObject(hBitmap);
- }
- return ;
- case WM_PAINT:
- hdc = BeginPaint(hwnd, &ps);
- if (hPalette)
- {
- SelectPalette(hdc, hPalette, FALSE);
- RealizePalette(hdc);
- }
- if (hBitmap)
- {
- DisplayDib(hdc,
- fHalftonePalette ? DibBitmapHandle(hdib) : hBitmap,
- iHscroll, iVscroll,
- cxClient, cyClient,
- wShow, fHalftonePalette);
- }
- EndPaint(hwnd, &ps);
- return ;
- case WM_QUERYNEWPALETTE:
- if (!hPalette)
- return FALSE;
- hdc = GetDC(hwnd);
- SelectPalette(hdc, hPalette, FALSE);
- RealizePalette(hdc);
- InvalidateRect(hwnd, NULL, TRUE);
- ReleaseDC(hwnd, hdc);
- return TRUE;
- case WM_PALETTECHANGED:
- if (!hPalette || (HWND)wParam == hwnd)
- return FALSE;
- hdc = GetDC(hwnd);
- SelectPalette(hdc, hPalette, FALSE);
- RealizePalette(hdc);
- UpdateColors(hdc);
- ReleaseDC(hwnd, hdc);
- break;
- case WM_DESTROY:
- if (hdib)
- DibDelete(hdib);
- if (hBitmap)
- DeleteObject(hBitmap);
- if (hPalette)
- DeleteObject(hPalette);
- PostQuitMessage();
- return ;
- }
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
//resource.h
- //{{NO_DEPENDENCIES}}
- // Microsoft Visual C++ 生成的包含文件。
- // 供 Dibble.rc 使用
- //
- #define IDM_FILE_OPEN 40001
- #define IDM_FILE_SAVE 40002
- #define IDM_FILE_PRINT 40003
- #define IDM_FILE_PROPERTIES 40004
- #define IDM_APP_EXIT 40005
- #define IDM_EDIT_CUT 40006
- #define IDM_EDIT_COPY 40007
- #define IDM_EDIT_PASTE 40008
- #define IDM_EDIT_DELETE 40009
- #define IDM_EDIT_FLIP 40010
- #define IDM_EDIT_ROTATE 40011
- #define IDM_SHOW_NORMAL 40012
- #define IDM_SHOW_CENTER 40013
- #define IDM_SHOW_STRETCH 40014
- #define IDM_SHOW_ISOSTRETCH 40015
- #define IDM_PAL_NONE 40016
- #define IDM_PAL_DIBTABLE 40017
- #define IDM_PAL_HALFTONE 40018
- #define IDM_PAL_ALLPURPOSE 40019
- #define IDM_PAL_GRAY2 40020
- #define IDM_PAL_GRAY3 40021
- #define IDM_PAL_GRAY4 40022
- #define IDM_PAL_GRAY8 40023
- #define IDM_PAL_GRAY16 40024
- #define IDM_PAL_GRAY32 40025
- #define IDM_PAL_GRAY64 40026
- #define IDM_PAL_GRAY128 40027
- #define IDM_PAL_GRAY256 40028
- #define IDM_PAL_RGB222 40029
- #define IDM_PAL_RGB333 40030
- #define IDM_PAL_RGB444 40031
- #define IDM_PAL_RGB555 40032
- #define IDM_PAL_RGB666 40033
- #define IDM_PAL_RGB775 40034
- #define IDM_PAL_RGB757 40035
- #define IDM_PAL_RGB577 40036
- #define IDM_PAL_RGB884 40037
- #define IDM_PAL_RGB848 40038
- #define IDM_PAL_RGB488 40039
- #define IDM_CONVERT_01 40040
- #define IDM_CONVERT_04 40041
- #define IDM_CONVERT_08 40042
- #define IDM_CONVERT_16 40043
- #define IDM_CONVERT_24 40044
- #define IDM_CONVERT_32 40045
- #define IDM_APP_ABOUT 40046
- #define IDM_PAL_OPT_POP4 40047
- #define IDM_PAL_OPT_POP5 40048
- #define IDM_PAL_OPT_POP6 40049
- #define IDM_PAL_OPT_MEDCUT 40050
- // Next default values for new objects
- //
- #ifdef APSTUDIO_INVOKED
- #ifndef APSTUDIO_READONLY_SYMBOLS
- #define _APS_NEXT_RESOURCE_VALUE 103
- #define _APS_NEXT_COMMAND_VALUE 40040
- #define _APS_NEXT_CONTROL_VALUE 1001
- #define _APS_NEXT_SYMED_VALUE 101
- #endif
- #endif
//Dibble.rc
- // Microsoft Visual C++ generated resource script.
- //
- #include "resource.h"
- #define APSTUDIO_READONLY_SYMBOLS
- /////////////////////////////////////////////////////////////////////////////
- //
- // Generated from the TEXTINCLUDE 2 resource.
- //
- #include "winres.h"
- /////////////////////////////////////////////////////////////////////////////
- #undef APSTUDIO_READONLY_SYMBOLS
- /////////////////////////////////////////////////////////////////////////////
- // 中文(简体,中国) resources
- #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
- LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
- #ifdef APSTUDIO_INVOKED
- /////////////////////////////////////////////////////////////////////////////
- //
- // TEXTINCLUDE
- //
- TEXTINCLUDE
- BEGIN
- "resource.h\0"
- END
- TEXTINCLUDE
- BEGIN
- "#include ""winres.h""\r\n"
- "\0"
- END
- TEXTINCLUDE
- BEGIN
- "\r\n"
- "\0"
- END
- #endif // APSTUDIO_INVOKED
- /////////////////////////////////////////////////////////////////////////////
- //
- // Menu
- //
- DIBBLE MENU
- BEGIN
- POPUP "&File"
- BEGIN
- MENUITEM "&Open...\tCtrl+O", IDM_FILE_OPEN
- MENUITEM "&Save...\tCtrl+S", IDM_FILE_SAVE
- MENUITEM SEPARATOR
- MENUITEM "&Print...\tCtrl+P", IDM_FILE_PRINT
- MENUITEM SEPARATOR
- MENUITEM "Propert&ies...", IDM_FILE_PROPERTIES
- MENUITEM SEPARATOR
- MENUITEM "E&xit", IDM_APP_EXIT
- END
- POPUP "&Edit"
- BEGIN
- MENUITEM "Cu&t\tCtrl+X", IDM_EDIT_CUT
- MENUITEM "&Copy\tCtrl+C", IDM_EDIT_COPY
- MENUITEM "&Paste\tCtrl+V", IDM_EDIT_PASTE
- MENUITEM "&Delete\tDelete", IDM_EDIT_DELETE
- MENUITEM SEPARATOR
- MENUITEM "&Flip", IDM_EDIT_FLIP
- MENUITEM "&Rotate", IDM_EDIT_ROTATE
- END
- POPUP "&Show"
- BEGIN
- MENUITEM "&Actual Size", IDM_SHOW_NORMAL, CHECKED
- MENUITEM "&Center", IDM_SHOW_CENTER
- MENUITEM "&Stretch to Window", IDM_SHOW_STRETCH
- MENUITEM "Stretch &Isotropically", IDM_SHOW_ISOSTRETCH
- END
- POPUP "&Palette"
- BEGIN
- MENUITEM "&None", IDM_PAL_NONE, CHECKED
- MENUITEM "&Dib ColorTable", IDM_PAL_DIBTABLE
- MENUITEM "&Halftone", IDM_PAL_HALFTONE
- MENUITEM "&All-Purpose", IDM_PAL_ALLPURPOSE
- POPUP "&Gray Shades"
- BEGIN
- MENUITEM "&1. 2 Grays ", IDM_PAL_GRAY2
- MENUITEM "&2. 3 Grays", IDM_PAL_GRAY3
- MENUITEM "&3. 4 Grays", IDM_PAL_GRAY4
- MENUITEM "&4. 8 Grays", IDM_PAL_GRAY8
- MENUITEM "&5. 16 Grays", IDM_PAL_GRAY16
- MENUITEM "&6. 32 Grays", IDM_PAL_GRAY32
- MENUITEM "&7. 64 Grays", IDM_PAL_GRAY64
- MENUITEM "&8. 128 Grays", IDM_PAL_GRAY128
- MENUITEM "&9. 256 Grays", IDM_PAL_GRAY256
- END
- POPUP "&Uniform Colors"
- BEGIN
- MENUITEM "&1. 2R×2G×2B (8)", IDM_PAL_RGB222
- MENUITEM "&2. 3R×3G×3B (27)", IDM_PAL_RGB333
- MENUITEM "&3. 4R×4G×4B (64)", IDM_PAL_RGB444
- MENUITEM "&4. 5R×5G×5B (125)", IDM_PAL_RGB555
- MENUITEM "&5. 6R×6G×6B (216)", IDM_PAL_RGB666
- MENUITEM "&6. 7R×7G×5B (245)", IDM_PAL_RGB775
- MENUITEM "&7. 7R×5G×7B (245)", IDM_PAL_RGB757
- MENUITEM "&8. 5R×7G×7B (245)", IDM_PAL_RGB577
- MENUITEM "&9. 8R×8G×4B (256)", IDM_PAL_RGB884
- MENUITEM "&A. 8R×4G×8B (256)", IDM_PAL_RGB848
- MENUITEM "&B. 4R×8G×8B (256)", IDM_PAL_RGB488
- END
- POPUP "&Optimized"
- BEGIN
- MENUITEM "&1. Popularity Algorithm (4 bits)", IDM_PAL_OPT_POP4
- MENUITEM "&2. Popularity Algorithm (5 bits)", IDM_PAL_OPT_POP5
- MENUITEM "&3. Popularity Algorithm (6 bits)", IDM_PAL_OPT_POP6
- MENUITEM "&4. Median Cut Algorithm (4 bits)", IDM_PAL_OPT_MEDCUT
- END
- END
- POPUP "Con&vert"
- BEGIN
- MENUITEM "&1. to 1 bit per pixel", IDM_CONVERT_01
- MENUITEM "&2. to 4 bits per Pixel", IDM_CONVERT_04
- MENUITEM "&3. to 8 bit per pixel", IDM_CONVERT_08
- MENUITEM "&4. to 16 bits per Pixel", IDM_CONVERT_16
- MENUITEM "&5. to 24 bit per pixel", IDM_CONVERT_24
- MENUITEM "&6. to 32 bits per Pixel", IDM_CONVERT_32
- END
- POPUP "&Help"
- BEGIN
- MENUITEM "&About", IDM_APP_ABOUT
- END
- END
- /////////////////////////////////////////////////////////////////////////////
- //
- // Accelerator
- //
- DIBBLE ACCELERATORS
- BEGIN
- "C", IDM_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
- "X", IDM_EDIT_CUT, VIRTKEY, CONTROL, NOINVERT
- VK_DELETE, IDM_EDIT_DELETE, VIRTKEY, NOINVERT
- "V", IDM_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT
- "O", IDM_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
- "P", IDM_FILE_PRINT, VIRTKEY, CONTROL, NOINVERT
- "S", IDM_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT
- END
- #endif // 中文(简体,中国) resources
- /////////////////////////////////////////////////////////////////////////////
- #ifndef APSTUDIO_INVOKED
- /////////////////////////////////////////////////////////////////////////////
- //
- // Generated from the TEXTINCLUDE 3 resource.
- //
- /////////////////////////////////////////////////////////////////////////////
- #endif // not APSTUDIO_INVOKED
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
- /*--------------------------------------------------------
- DIBHELP.H Header file for DIBHELP.C
- --------------------------------------------------------*/
- #pragma once
- #include <windows.h>
- typedef void* HDIB;
- //DIBHELP.C中的函数
- BOOL DibIsValid(HDIB hdib); //Dib文件是否有效
- HBITMAP DibBitmapHandle(HDIB hdib);
- int DibWidth(HDIB hdib);
- int DibHeight(HDIB hdib);
- int DibBitCount(HDIB hdib);
- int DibRowLength(HDIB hdib); //每行像素数:4的倍数
- int DibNumColors(HDIB hdib);
- DWORD DibMask(HDIB hdib, int i);//获取颜色掩码
- int DibRShift(HDIB hdib, int i);//
- int DibLShift(HDIB hdib, int i);
- int DibCompression(HDIB hdib); //获取biCompression字段的值
- BOOL DibIsAddressable(HDIB hdib);//是否被压缩,DibIsNotCompressed
- DWORD DibInfoHeaderSize(HDIB hdib);
- DWORD DibMaskSize(HDIB hdib);
- DWORD DibColorSize(HDIB hdib);
- DWORD DibInfoSize(HDIB hdib);
- DWORD DibBitsSize(HDIB hdib);
- DWORD DibTotalSize(HDIB hdib);
- BITMAPINFOHEADER* DibInfoHeaderPtr(HDIB hdib);
- DWORD* DibMaskPtr(HDIB hdib);
- void* DibBitsPtr(HDIB hdib);
- BOOL DibGetColor(HDIB hdib, int index, RGBQUAD* prgb);
- BOOL DibSetColor(HDIB hdib, int index, RGBQUAD*prgb);
- BYTE* DibPixelPtr(HDIB hdib, int x, int y);
- DWORD DibGetPixel(HDIB hdib, int x, int y);
- BOOL DibSetPixel(HDIB hdib, int x, int y, DWORD dwPixel);
- BOOL DibGetPixelColor(HDIB hdib, int x, int y, RGBQUAD* prgb);
- BOOL DibSetPixelColor(HDIB hdib, int x, int y, RGBQUAD* prgb);
- HDIB DibCreateFromInfo(BITMAPINFO* pbmi);
- BOOL DibDelete(HDIB hdib);
- HDIB DibCreate(int cx, int cy, int cBits, int cColors);
- HDIB DibCopy(HDIB hdibSrc, BOOL fRotate);
- BITMAPINFO* DibCopyToPackedDib(HDIB hdib, BOOL fUsedGlobal);
- HDIB DibCopyFromPackedDib(BITMAPINFO* pPackedDib);
- HDIB DibFileLoad(const TCHAR* szFileName);
- BOOL DibFileSave(HDIB hdib, const TCHAR* szFileName);
- HBITMAP DibCopyToDdb(HDIB hdib, HWND hwnd, HPALETTE hPalette);
- HDIB DibCreateFromDdb(HBITMAP hBitmap); //该函数课本没有给出实现
- /*----------------------------------------------------------
- DibFlipHorizontal:调用没有优化的DibSetPixel和DibGetPixel
- ----------------------------------------------------------*/
- HDIB DibFlipHorizontal(HDIB hdibSrc);
- /*----------------------------------------------------------
- DibRotateRight:调用优化过的DibSetPixelx和DibGetPixelx
- ----------------------------------------------------------*/
- HDIB DibRotateRight(HDIB hdibSrc);
- /*----------------------------------------------------------
- 快速无边界检查的gets和Sets宏
- ----------------------------------------------------------*/
- #define DibPixelPtr1(hdib,x,y) (((*(PBYTE**)hdib)[y]) +((x)>>3))
- #define DibPixelPtr4(hdib,x,y) (((*(PBYTE**)hdib)[y]) +((x)>>1))
- #define DibPixelPtr8(hdib,x,y) (((*(PBYTE**)hdib)[y]) + (x) )
- #define DibPixelPtr16(hdib,x,y) ((WORD*)(((*(PBYTE**)hdib)[y]) + (x)*2 ))
- #define DibPixelPtr24(hdib,x,y) ((RGBTRIPLE*)(((*(PBYTE**)hdib)[y]) + (x)*3 ))
- #define DibPixelPtr32(hdib,x,y) ((DWORD*)(((*(PBYTE**)hdib)[y]) + (x)*4 ))
- #define DibGetPixel1(hdib,x,y) (0x01&(*DibPixelPtr1(hdib,x,y) >> (7 -((x)&7))))
- #define DibGetPixel4(hdib,x,y) (0x0F &(*DibPixelPtr4(hdib,x,y)>>((x)&1 ? 0 : 4)))
- #define DibGetPixel8(hdib,x,y) (*DibPixelPtr8(hdib,x,y))
- #define DibGetPixel16(hdib,x,y) (*DibPixelPtr16(hdib,x,y))
- #define DibGetPixel24(hdib,x,y) (*DibPixelPtr24(hdib,x,y))
- #define DibGetPixel32(hdib,x,y) (*DibPixelPtr32(hdib,x,y))
- #define DibSetPixel1(hdib, x, y, p) \
- ((*DibPixelPtr1(hdib, x, y) &= ~( << ( - ((x)& )))), \
- (*DibPixelPtr1(hdib, x, y) |= ((p) << ( - ((x)& )))))
- #define DibSetPixel4(hdib, x, y, p) \
- ((*DibPixelPtr4(hdib, x, y) &= (0x0F << ((x)& ? : ))), \
- (*DibPixelPtr4(hdib, x, y) |= ((p) << ((x)& ? : ))))
- #define DibSetPixel8(hdib, x, y, p) (* DibPixelPtr8 (hdib, x, y) = p)
- #define DibSetPixel16(hdib, x, y, p) (* DibPixelPtr16 (hdib, x, y) = p)
- #define DibSetPixel24(hdib, x, y, p) (* DibPixelPtr24 (hdib, x, y) = p)
- #define DibSetPixel32(hdib, x, y, p) (* DibPixelPtr32 (hdib, x, y) = p)
//DibHelp.c
- /*-------------------------------------------------------------
- DIBHELP.C -- DIB Section Helper Routines
- (c)Charles Petzold,1998
- -------------------------------------------------------------*/
- #include <windows.h>
- #include "DibHelp.h"
- #define HDIB_SIGNATURE (*(int*)"Dib ")
- typedef struct
- {
- PBYTE* ppRow; //像素位的行指针,必须是第一个字段,为后面的宏操作更容易设计的。
- //第一个指针指向DIB位图视觉上最上面的一行像素,最后一个指针指向
- //DIB图像最后一行的像素,和pBits字段一样(也就是pBits也要被存成
- //这样的格式)
- int iSignature; //="Dib "
- HBITMAP hBitmap;//接收从CreateDIBSection返回的句柄,明显返回的是设备无关的位图,
- //但可以直接被BitBlt或StretchBlt
- BYTE* pBits; //指向位图的像素数据,其值在CreateDIBSection函数中被设定。其所指
- //的内存块由操作系统管理,但应用程序可以访问该内存块。删除位图
- //句柄后,该内存块自动被删除
- DIBSECTION ds; //可以用GetObject获得位图信图,存入该结构体
- int iRShift[]; //分别存入R、G、B3种颜色遮罩需左移的值
- int iLShift[]; //
- }DIBSTRUCT, *PDIBSTRUCT;
- /*----------------------------------------------------------------------------------
- DibIsValid:如果hdib指向一个有效的DIBSTRUCT结构体时返回TRUE
- -----------------------------------------------------------------------------------*/
- BOOL DibIsValid(HDIB hdib)
- {
- DIBSTRUCT* pdib = hdib;
- if (pdib == NULL)
- return FALSE;
- //检查是否有读取指定内存的内容的权限,参数1为要检查的内存指针,参数2为要检查的内存块大小
- if (IsBadReadPtr(pdib, sizeof(DIBSTRUCT)))
- return FALSE;
- if (pdib->iSignature != HDIB_SIGNATURE) //自定义的DIB位图标识符
- return FALSE;
- return TRUE;
- }
- /*----------------------------------------------------------------------------------
- DibBitmapHandle:返回DIB Section位图对象的句柄hBitmap
- -----------------------------------------------------------------------------------*/
- HBITMAP DibBitmapHandle(HDIB hdib)
- {
- if (!DibIsValid(hdib))
- return NULL;
- return ((PDIBSTRUCT)hdib)->hBitmap;
- }
- /*----------------------------------------------------------------------------------
- DibWidth:返回位图的宽度(单位字节)
- -----------------------------------------------------------------------------------*/
- int DibWidth(HDIB hdib)
- {
- if (!DibIsValid(hdib))
- return ;
- return ((PDIBSTRUCT)hdib)->ds.dsBm.bmWidth;
- }
- /*----------------------------------------------------------------------------------
- DibHeight:返回位图的高度(单位字节)
- -----------------------------------------------------------------------------------*/
- int DibHeight(HDIB hdib)
- {
- if (!DibIsValid(hdib))
- return ;
- return ((PDIBSTRUCT)hdib)->ds.dsBm.bmHeight;
- }
- /*----------------------------------------------------------------------------------
- DibBitCount:返回每像素的位数
- -----------------------------------------------------------------------------------*/
- int DibBitCount(HDIB hdib)
- {
- if (!DibIsValid(hdib))
- return ;
- return ((PDIBSTRUCT)hdib)->ds.dsBm.bmBitsPixel;
- }
- /*----------------------------------------------------------------------------------
- DibRowLength:返回每行像素的大小(单位:字节):4的倍数
- -----------------------------------------------------------------------------------*/
- int DibRowLength(HDIB hdib)
- {
- if (!DibIsValid(hdib))
- return ;
- return * ((DibWidth(hdib)*DibBitCount(hdib) + ) / );
- }
- /*----------------------------------------------------------------------------------
- DibNumColors:返回颜色表的颜色数目,无颜色表时返回0
- -----------------------------------------------------------------------------------*/
- int DibNumColors(HDIB hdib)
- {
- PDIBSTRUCT pdib = hdib;
- if (!DibIsValid(hdib))
- return ;
- if (pdib->ds.dsBmih.biClrUsed != )
- {
- return pdib->ds.dsBmih.biClrUsed;
- } else if (DibBitCount(hdib) <= )
- {
- return << DibBitCount(hdib); //2^bBitCount,如1位则2种颜色,8位256色
- }
- return ;
- }
- /*----------------------------------------------------------------------------------
- DibMask:返回3种颜色遮罩其中的一种,如红色遮罩
- -----------------------------------------------------------------------------------*/
- DWORD DibMask(HDIB hdib, int i)
- {
- PDIBSTRUCT pdib = hdib;
- if (!DibIsValid(hdib) || i< || i>)
- return ;
- return pdib->ds.dsBitfields[i];//0—红色;1—绿色;2—蓝色
- }
- /*----------------------------------------------------------------------------------
- DibRShift:返回需右移的位数
- -----------------------------------------------------------------------------------*/
- int DibRShift(HDIB hdib, int i)
- {
- PDIBSTRUCT pdib = hdib;
- if (!DibIsValid(hdib) || i< || i>)
- return ;
- return pdib->iRShift[i];
- }
- /*----------------------------------------------------------------------------------
- DibLShift:返回需左移的位数
- -----------------------------------------------------------------------------------*/
- int DibLShift(HDIB hdib, int i)
- {
- PDIBSTRUCT pdib = hdib;
- if (!DibIsValid(hdib) || i< || i>)
- return ;
- return pdib->iLShift[i];
- }
- /*----------------------------------------------------------------------------------
- DibCompression: 获取biCompression字段的值
- -----------------------------------------------------------------------------------*/
- int DibCompression(HDIB hdib)
- {
- if (!DibIsValid(hdib))
- return ;
- return ((PDIBSTRUCT)hdib)->ds.dsBmih.biCompression;
- }
- //是否被压缩,DibIsNotCompressed
- /*----------------------------------------------------------------------------------
- DibIsAddressable: 如果DIB没压缩则返回TRUE
- -----------------------------------------------------------------------------------*/
- BOOL DibIsAddressable(HDIB hdib)
- {
- int iCompression;
- if (!DibIsValid(hdib))
- return ;
- iCompression = DibCompression(hdib);
- if (iCompression == BI_RGB || iCompression == BI_BITFIELDS)
- return TRUE;
- return FALSE;
- }
- /*----------------------------------------------------------------------------------
- 下面这些函数返回DIB Section可能出现的各种变量信息,这些函数的目的是为了将DIB Section
- 转换为紧凑DIB或保存文件时使用
- -----------------------------------------------------------------------------------*/
- DWORD DibInfoHeaderSize(HDIB hdib) //文件信息头BITMAPINFOHEADER(不含颜色遮罩、颜色表)等
- {
- if (!DibIsValid(hdib))
- return ;
- return ((PDIBSTRUCT)hdib)->ds.dsBmih.biSize;
- }
- DWORD DibMaskSize(HDIB hdib)
- {
- PDIBSTRUCT pdib = hdib;
- if (!DibIsValid(hdib))
- return ;
- if (pdib->ds.dsBmih.biCompression == BI_BITFIELDS)
- return * sizeof(DWORD);
- return ;
- }
- DWORD DibColorSize(HDIB hdib)
- {
- return DibNumColors(hdib)*sizeof(RGBQUAD);
- }
- DWORD DibInfoSize(HDIB hdib)
- {
- return DibInfoHeaderSize(hdib) + DibMaskSize(hdib) + DibColorSize(hdib);
- }
- DWORD DibBitsSize(HDIB hdib)
- {
- PDIBSTRUCT pdib = hdib;
- if (!DibIsValid(hdib))
- return ;
- if (pdib->ds.dsBmih.biSizeImage != )
- {
- return pdib->ds.dsBmih.biSizeImage;
- }
- return DibHeight(hdib)*DibRowLength(hdib);
- }
- DWORD DibTotalSize(HDIB hdib) //整个紧凑型DIB的大小
- {
- return DibInfoSize(hdib) + DibBitsSize(hdib);
- }
- /*----------------------------------------------------------------------------------
- 下面这些函数返回DIB Section各部分的指针
- -----------------------------------------------------------------------------------*/
- BITMAPINFOHEADER* DibInfoHeaderPtr(HDIB hdib)
- {
- if (!DibIsValid(hdib))
- return NULL;
- return &(((PDIBSTRUCT)hdib)->ds.dsBmih);
- }
- DWORD* DibMaskPtr(HDIB hdib)
- {
- PDIBSTRUCT pdib = hdib;
- if (!DibIsValid(hdib))
- return NULL;
- return pdib->ds.dsBitfields;//因为这个字段是个数组,数组名是个指针。
- }
- void* DibBitsPtr(HDIB hdib)
- {
- if (!DibIsValid(hdib))
- return NULL;
- return ((PDIBSTRUCT)hdib)->pBits;
- }
- /*----------------------------------------------------------------------------------
- DibGetColor:从DIB颜色表中获得指定索引号处的颜色,放在prgb结构体中
- -----------------------------------------------------------------------------------*/
- BOOL DibGetColor(HDIB hdib, int index, RGBQUAD* prgb)
- {
- PDIBSTRUCT pdib = hdib;
- HDC hdcMem;
- int iReturn;
- if (!DibIsValid(hdib))
- return FALSE;
- hdcMem = CreateCompatibleDC(NULL);
- SelectObject(hdcMem, pdib->hBitmap);
- iReturn = GetDIBColorTable(hdcMem, index, , prgb); //API函数
- DeleteDC(hdcMem);
- return iReturn ? TRUE : FALSE;
- }
- /*----------------------------------------------------------------------------------
- DibSetColor:prgb结构体颜色设置到DIB颜色表中
- -----------------------------------------------------------------------------------*/
- BOOL DibSetColor(HDIB hdib, int index, RGBQUAD*prgb)
- {
- PDIBSTRUCT pdib = hdib;
- HDC hdcMem;
- int iReturn;
- if (!DibIsValid(hdib))
- return FALSE;
- hdcMem = CreateCompatibleDC(NULL);
- SelectObject(hdcMem, pdib->hBitmap);
- iReturn = SetDIBColorTable(hdcMem, index, , prgb); //API函数
- DeleteDC(hdcMem);
- return iReturn ? TRUE : FALSE;
- }
- /*----------------------------------------------------------------------------------
- DibPixelPtr:返回(x,y)处的像素位指针
- -----------------------------------------------------------------------------------*/
- BYTE* DibPixelPtr(HDIB hdib, int x, int y)
- {
- if (!DibIsAddressable(hdib))
- return NULL;
- if (x < || x >= DibWidth(hdib) || y < || y >= DibHeight(hdib))
- return NULL;
- //x每次加1时,指针后移BitCount/8个字节,所以对于每像素1或4位时,
- //获取每个字节的像素还需移位才能读出像素值
- //对于8、16、24或32位的,每bitCount/8个字节
- //具体的处理 见DibGetPixel或DibSetPixel函数的处理。
- return (((PDIBSTRUCT)hdib)->ppRow)[y] + (x* DibBitCount(hdib) >> );
- }
- /*----------------------------------------------------------------------------------
- DibGetPixel:返回(x,y)处的像素值
- -----------------------------------------------------------------------------------*/
- DWORD DibGetPixel(HDIB hdib, int x, int y)
- {
- PBYTE pPixel;
- pPixel = DibPixelPtr(hdib, x, y);
- if (!pPixel)
- return ;
- switch (DibBitCount(hdib))
- {
- //快速求余法:X % (2^N) == X & (2^N - 1),
- case : return 0x01 & (*pPixel >> ( - (x & )));
- case : return 0x0F & (*pPixel >> (x & ? : ));//x为奇数是,取低4位,偶数取高4位
- case : return *pPixel;
- case :return *(WORD*)pPixel;
- case :return 0x00FFFFFF & *(DWORD*)pPixel;
- case :return *(DWORD*)pPixel;
- }
- return ;
- }
- /*----------------------------------------------------------------------------------
- DibSetPixel:设置(x,y)处的像素值
- -----------------------------------------------------------------------------------*/
- BOOL DibSetPixel(HDIB hdib, int x, int y, DWORD dwPixel)
- {
- PBYTE pPixel;
- pPixel = DibPixelPtr(hdib, x, y);
- if (!pPixel)
- return FALSE;
- switch (DibBitCount(hdib))
- {
- case :
- *pPixel &= ~( << ( - (x & ))); //取出该字节中除x处外的其余像素数
- *pPixel |= dwPixel << ( - (x & ));//将颜色值加入上述的X处。
- break;
- case :
- *pPixel &= 0x0F << (x & ? : );
- *pPixel |= dwPixel << (x & ? : );
- break;
- case :
- *pPixel = (BYTE)dwPixel;
- break;
- case :
- *(WORD*)pPixel = (WORD)dwPixel;
- break;
- case :
- *(RGBTRIPLE*)pPixel = *(RGBTRIPLE*)&dwPixel;
- break;
- case :
- *(DWORD*)pPixel = dwPixel;
- break;
- default:
- return FALSE;
- }
- return TRUE;
- }
- /*----------------------------------------------------------------------------------
- DibGetPixelColor:获得(x,y)处的颜色值,并放入prgb所指的结构体中
- -----------------------------------------------------------------------------------*/
- BOOL DibGetPixelColor(HDIB hdib, int x, int y, RGBQUAD* prgb)
- {
- DWORD dwPixel;
- int iBitCount;
- PDIBSTRUCT pdib = hdib;
- //获得每像素位的大小,也可以使用它来作有效性验证
- if ( == (iBitCount = DibBitCount(hdib)))
- return FALSE;
- //获取像素位的值,返回DWORD,该值可能是索引或里面含有RGB值
- dwPixel = DibGetPixel(hdib, x, y);
- //如果是8位或以下的,该值为颜色表索引
- if (iBitCount <= )
- return DibGetColor(hdib, (int)dwPixel, prgb);
- else if (iBitCount == )
- {
- *(RGBTRIPLE*)prgb = *(RGBTRIPLE*)&dwPixel;
- prgb->rgbReserved = ;
- } else if (iBitCount == && pdib->ds.dsBmih.biCompression == BI_RGB)
- {
- *prgb = *(RGBQUAD*)&dwPixel;
- }
- //此外的情况,使用颜色遮罩和移位
- else
- {
- //下面等号右边的式子,执行顺序先用掩码取出dwPixel的相应颜色,再右移,最后左移。
- prgb->rgbRed = (BYTE)((pdib->ds.dsBitfields[] & dwPixel) >> pdib->iRShift[] << pdib->iLShift[]);
- prgb->rgbGreen = (BYTE)((pdib->ds.dsBitfields[] & dwPixel) >> pdib->iRShift[] << pdib->iLShift[]);
- prgb->rgbBlue = (BYTE)((pdib->ds.dsBitfields[] & dwPixel) >> pdib->iRShift[] << pdib->iLShift[]);
- }
- return TRUE;
- }
- /*----------------------------------------------------------------------------------
- DibSetPixelColor:获得(x,y)处的颜色值
- -----------------------------------------------------------------------------------*/
- BOOL DibSetPixelColor(HDIB hdib, int x, int y, RGBQUAD* prgb)
- {
- DWORD dwPixel;
- int iBitCount;
- PDIBSTRUCT pdib = hdib;
- //不要利用DIBs的颜色表来执行该函数的操作
- iBitCount = DibBitCount(hdib);
- if (iBitCount <= )
- return FALSE;
- //剩下来的步骤与GetPixelColor相反
- else if (iBitCount == )
- {
- *(RGBTRIPLE*)&dwPixel = *(RGBTRIPLE*)prgb;
- dwPixel &= 0x00FFFFFF;
- } else if (iBitCount == && pdib->ds.dsBmih.biCompression == BI_RGB)
- {
- *(RGBQUAD*)&dwPixel = *prgb;
- } else
- {
- //先将rgbRed由字节转为DWORD,再右移,最后左移
- dwPixel = (((DWORD)prgb->rgbRed >> pdib->iLShift[]) << pdib->iRShift[]);
- dwPixel |= (((DWORD)prgb->rgbGreen >> pdib->iLShift[]) << pdib->iRShift[]);
- dwPixel |= (((DWORD)prgb->rgbBlue >> pdib->iLShift[]) << pdib->iRShift[]);
- }
- DibSetPixel(hdib, x, y, dwPixel);
- return TRUE;
- }
- /*----------------------------------------------------------------------------------
- 根据遮罩颜色计算移位值,这些颜色遮罩来自于DibCreateFromInfo函数
- -----------------------------------------------------------------------------------*/
- static int MaskToRShift(DWORD dwMask)
- {
- int iShift;
- if ( == dwMask)
- return ;
- for (iShift = ; !(dwMask & ); iShift++) //最低位为0,则右移1位
- dwMask >>= ;
- return iShift;
- }
- static int MaskToLShift(DWORD dwMask)
- {
- int iShift;
- if ( == dwMask)
- return ;
- while (!(dwMask & )) //dwMask右侧的0移掉
- dwMask >>= ;
- for (iShift = ; dwMask & ; iShift++) //统计1的个数
- dwMask >>= ;
- return - iShift;
- }
- /*----------------------------------------------------------------------------------
- DibCreateFromInfo:
- 所有创建DIB的函数最后都要调用该函数。这个函数负责调用CreateDIBSection,
- 为DIBSTRUCT分配内存,并设置行指针
- -----------------------------------------------------------------------------------*/
- HDIB DibCreateFromInfo(BITMAPINFO* pbmi)
- {
- DIBSTRUCT* pdib;
- BYTE* pBits;
- HBITMAP hBitmap;
- int i, y, cy, iRowLength;
- //根据pbmi创建DIB Section位图,pBits指向今后要存入的像素位的空间地址(由系统管理)
- hBitmap = CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, &pBits, NULL, );
- if (NULL == hBitmap)
- return NULL;
- if (NULL == (pdib = malloc(sizeof(DIBSTRUCT))))
- {
- DeleteObject(hBitmap);
- return NULL;
- }
- pdib->iSignature = HDIB_SIGNATURE;
- pdib->hBitmap = hBitmap;
- pdib->pBits = pBits;
- //填充DIBSECTION结构
- GetObject(hBitmap, sizeof(DIBSECTION), &pdib->ds);
- //现在可以使用自定义的DIB信息函数,如DibCompression
- //如果压缩格式是BI_BITFIELDS,则计算掩码的移位
- if (DibCompression(pdib) == BI_BITFIELDS)
- {
- for (i = ; i < ; i++)
- {
- pdib->iLShift[i] = MaskToLShift(pdib->ds.dsBitfields[i]);
- pdib->iRShift[i] = MaskToRShift(pdib->ds.dsBitfields[i]);
- }
- }
- //如果是BI_RGB,但是16位或32位的,则设置bitFields和masks字段
- else if (DibCompression(pdib) == BI_RGB)
- {
- if (DibBitCount(pdib) == ) //RGB分别使用5-5-5型遮罩
- {
- pdib->ds.dsBitfields[] = 0x00007C00; //R Mask
- pdib->ds.dsBitfields[] = 0x000003E0; //G Mask
- pdib->ds.dsBitfields[] = 0x0000001F; //B Mask
- pdib->iRShift[] = ;
- pdib->iRShift[] = ;
- pdib->iRShift[] = ;
- pdib->iLShift[] = ;
- pdib->iLShift[] = ;
- pdib->iLShift[] = ;
- } else if (DibBitCount(pdib) == || DibBitCount(pdib) == ) //使用8-8-8型
- {
- pdib->ds.dsBitfields[] = 0x00FF0000; //R Mask
- pdib->ds.dsBitfields[] = 0x0000FF00; //G Mask
- pdib->ds.dsBitfields[] = 0x000000FF; //B Mask
- pdib->iRShift[] = ;
- pdib->iRShift[] = ;
- pdib->iRShift[] = ;
- pdib->iLShift[] = ;
- pdib->iLShift[] = ;
- pdib->iLShift[] = ;
- }
- }
- //分配DIB像素行指针数组
- cy = DibHeight(pdib);
- pdib->ppRow = malloc(cy*sizeof(BYTE*));
- if (NULL == pdib->ppRow)
- {
- free(pdib);
- DeleteObject(hBitmap);
- return NULL;
- }
- //初始化像素行指针数组,ppRow[0]设为图像视觉上的最顶行。
- iRowLength = DibRowLength(pdib);
- if (pbmi->bmiHeader.biHeight>) //位图从下到上存储
- {
- for (y = ; y < cy; y++)
- pdib->ppRow[y] = pBits + (cy - - y)*iRowLength;
- } else //从上到下存储
- {
- for (y = ; y < cy; y++)
- pdib->ppRow[y] = pBits + y*iRowLength;
- }
- return pdib;
- }
- /*----------------------------------------------------------------------------------
- DibDelete:删除DIBSTRUCT和在其中分配的内存
- -----------------------------------------------------------------------------------*/
- BOOL DibDelete(HDIB hdib)
- {
- DIBSTRUCT* pdib = hdib;
- if (!DibIsValid(hdib))
- return FALSE;
- free(pdib->ppRow);
- DeleteObject(pdib->hBitmap);
- free(pdib);
- return TRUE;
- }
- /*-----------------------------------------------------------------------------------
- DibCreate: 通过显式指定参数来构建HDIB()
- -----------------------------------------------------------------------------------*/
- HDIB DibCreate(int cx, int cy, int cBits, int cColors)
- {
- HDIB hdib;
- BITMAPINFO* pbmi;
- DWORD dwInfoSize;
- int cEntries = ;
- if (cx <= || cy <= ||
- ((cBits != ) && (cBits != ) && (cBits != ) &&
- (cBits != ) && (cBits != ) && (cBits != )))
- {
- return NULL;
- }
- if (cColors != )
- cEntries = cColors;
- else if (cBits <= )
- cEntries = << cBits;
- dwInfoSize = sizeof(BITMAPINFOHEADER) + (cEntries - )*sizeof(RGBQUAD);
- if (NULL == (pbmi = malloc(dwInfoSize)))
- {
- return NULL;
- }
- ZeroMemory(pbmi, dwInfoSize);
- pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- pbmi->bmiHeader.biWidth = cx;
- pbmi->bmiHeader.biHeight = cy;
- pbmi->bmiHeader.biPlanes = ;
- pbmi->bmiHeader.biBitCount = cBits;
- pbmi->bmiHeader.biCompression = BI_RGB;
- pbmi->bmiHeader.biSizeImage = ;
- pbmi->bmiHeader.biXPelsPerMeter = ;
- pbmi->bmiHeader.biYPelsPerMeter = ;
- pbmi->bmiHeader.biClrUsed = cColors;
- pbmi->bmiHeader.biClrImportant = ;
- hdib = DibCreateFromInfo(pbmi);
- free(pbmi);
- return hdib;
- }
- /*-----------------------------------------------------------------------------------
- DibCopyToInfo: 构建BITMAPINFO结构体.(主要供DibCopy和DibCopyToDdb函数使用)
- -----------------------------------------------------------------------------------*/
- static BITMAPINFO* DibCopyToInfo(HDIB hdib)
- {
- BITMAPINFO* pbmi;
- RGBQUAD* prgb;
- int i, iNumColors;
- if (!DibIsValid(hdib))
- return NULL;
- if (NULL == (pbmi = malloc(DibInfoSize(hdib))))
- return NULL;
- //复制BITMAPINFO信息头部分
- CopyMemory(pbmi, DibInfoHeaderPtr(hdib), sizeof(BITMAPINFOHEADER));
- //复制可能的颜色遮罩
- prgb = (RGBQUAD*)((BYTE*)pbmi + sizeof(BITMAPINFOHEADER));
- if (DibMaskSize(hdib))
- {
- CopyMemory(prgb, DibMaskPtr(hdib), * sizeof(DWORD));
- prgb = (RGBQUAD*)((BYTE*)prgb + * sizeof(DWORD));//将指针移到遮罩后,指向颜色表
- }
- //复制颜色表
- iNumColors = DibNumColors(hdib);
- for (i = ; i < iNumColors; i++)
- {
- DibGetColor(hdib, i, prgb + i); //每种颜色都是32位的。RGRQUAD也是32位的
- }
- return pbmi;
- }
- /*-----------------------------------------------------------------------------------
- DibCopy: 从一个己经存在的DIB Section去创建一个新的DIB Section(注意:可以会交换
- 宽度与高度)
- -----------------------------------------------------------------------------------*/
- HDIB DibCopy(HDIB hdibSrc, BOOL fRotate)
- {
- BITMAPINFO* pbmi;
- BYTE *pBitsSrc, *pBitsDst;
- HDIB hdibDst;
- if (!DibIsValid(hdibSrc))
- return NULL;
- if (NULL == (pbmi = DibCopyToInfo(hdibSrc)))
- return NULL;
- if (fRotate)
- {
- pbmi->bmiHeader.biWidth = DibHeight(hdibSrc);
- pbmi->bmiHeader.biHeight = DibWidth(hdibSrc);
- }
- hdibDst = DibCreateFromInfo(pbmi);
- free(pbmi);
- if (!fRotate) //不旋转时直接复制像素数据。旋转时,需自行处理
- {
- pBitsSrc = DibBitsPtr(hdibSrc);
- pBitsDst = DibBitsPtr(hdibDst);
- CopyMemory(pBitsDst, pBitsSrc, DibBitsSize(hdibSrc));
- }
- return hdibDst;
- }
- /*-----------------------------------------------------------------------------------
- DibCopyToPackedDib:
- 通常用于保存DIBs或将DIBs传输到剪贴板。当传输到剪贴板时,第2个参数必须设为TRUE,以便
- 分配一个全局共享内存
- -----------------------------------------------------------------------------------*/
- BITMAPINFO* DibCopyToPackedDib(HDIB hdib, BOOL fUsedGlobal)
- {
- BITMAPINFO* pPackedDib;
- DWORD dwDibSize;
- HGLOBAL hGlobal = NULL;
- PDIBSTRUCT pdib = hdib;
- RGBQUAD* prgb;
- BYTE* pBits;
- int iNumColors;
- HDC hdcMem;
- if (!DibIsValid(hdib))
- return NULL;
- //为紧凑型DIB分配内存
- dwDibSize = DibTotalSize(hdib);
- if (fUsedGlobal)
- {
- hGlobal = GlobalAlloc(GHND | GMEM_SHARE, dwDibSize);
- pPackedDib = GlobalLock(hGlobal);
- } else
- {
- pPackedDib = malloc(dwDibSize);
- }
- if (NULL == pPackedDib)
- return NULL;
- //复制信息头
- CopyMemory(pPackedDib, &pdib->ds.dsBmih, sizeof(BITMAPINFOHEADER));
- prgb = (RGBQUAD*)((BYTE*)pPackedDib + sizeof(BITMAPINFOHEADER));
- //复制可能的颜色遮罩
- if (pdib->ds.dsBmih.biCompression == BI_BITFIELDS)
- {
- CopyMemory(prgb, pdib->ds.dsBitfields, * sizeof(DWORD));
- prgb = (RGBQUAD*)((BYTE*)prgb + * sizeof(DWORD));
- }
- //复制颜色表
- if (iNumColors = DibNumColors(hdib))
- {
- hdcMem = CreateCompatibleDC(NULL);
- SelectObject(hdcMem, pdib->hBitmap);
- GetDIBColorTable(hdcMem, , iNumColors, prgb);
- DeleteDC(hdcMem);
- }
- //复制像素数据
- pBits = (BYTE*)(prgb + iNumColors);
- CopyMemory(pBits, pdib->pBits, DibBitsSize(hdib));
- //如果最后一个参数是TRUE,解锁全局内存块,并将全局句块转化为指针返回
- if (fUsedGlobal)
- {
- GlobalUnlock(hGlobal);
- pPackedDib = (BITMAPINFO*)hGlobal;
- }
- return pPackedDib;
- }
- /*-----------------------------------------------------------------------------------
- DibCopyFromPackedDib:通常用于从剪贴板中粘贴DIBs
- -----------------------------------------------------------------------------------*/
- HDIB DibCopyFromPackedDib(BITMAPINFO* pPackedDib)
- {
- BYTE* pBits;
- DWORD dwInfoSize, dwMaskSize, dwColorSize;
- int iBitCount;
- PDIBSTRUCT pdib;
- //获取信息头类型,并做有效性验证
- dwInfoSize = pPackedDib->bmiHeader.biSize;
- if (dwInfoSize != sizeof(BITMAPCOREHEADER) &&
- dwInfoSize != sizeof(BITMAPINFOHEADER) &&
- dwInfoSize != sizeof(BITMAPV4HEADER) &&
- dwInfoSize != sizeof(BITMAPV5HEADER))
- {
- return NULL;
- }
- //获取可能的颜色遮罩的大小
- if (dwInfoSize == sizeof(BITMAPINFOHEADER) &&
- pPackedDib->bmiHeader.biCompression == BI_BITFIELDS)
- {
- dwMaskSize = * sizeof(DWORD);
- } else
- {
- dwMaskSize = ;
- }
- //获取颜色表的大小
- if (dwInfoSize == sizeof(BITMAPCOREHEADER))
- {
- iBitCount = ((BITMAPCOREHEADER*)pPackedDib)->bcBitCount;
- if (iBitCount <= )
- {
- dwColorSize = ( << (iBitCount))*sizeof(RGBTRIPLE);
- } else
- dwColorSize = ;
- } else //所有非OS/2的DIBs
- {
- if (pPackedDib->bmiHeader.biClrUsed >)
- {
- dwColorSize = pPackedDib->bmiHeader.biClrUsed*sizeof(RGBQUAD);
- } else if (pPackedDib->bmiHeader.biBitCount <= )
- {
- dwColorSize = ( << pPackedDib->bmiHeader.biBitCount)*sizeof(RGBQUAD);
- } else
- {
- dwColorSize = ;
- }
- }
- //最后,获得pPackedDIB像素位的指针
- pBits = (BYTE*)pPackedDib + dwInfoSize + dwMaskSize + dwColorSize;
- //创建HDIB
- pdib = DibCreateFromInfo(pPackedDib);
- //复制像素位数据
- CopyMemory(pdib->pBits, pBits, DibBitsSize(pdib));
- return pdib;
- }
- /*----------------------------------------------------------------------------------
- DibFileLoad:从DIB文件中创建DIB Section
- -----------------------------------------------------------------------------------*/
- HDIB DibFileLoad(const TCHAR* szFileName)
- {
- HANDLE hFile;
- BITMAPFILEHEADER bmfh;
- BITMAPINFO* pbmi;
- BOOL bSuccess;
- DWORD dwInfoSize, dwBytesRead, dwBitsSize;
- HDIB hDib;
- //打开文件(设为可读可写)
- hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
- OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
- if (hFile == INVALID_HANDLE_VALUE)
- return NULL;
- //读取文件头信息
- bSuccess = ReadFile(hFile, &bmfh, sizeof(BITMAPFILEHEADER), &dwBytesRead, NULL);
- if (!bSuccess || (dwBytesRead != sizeof(BITMAPFILEHEADER))
- || (bmfh.bfType != *(WORD*)"BM"))
- {
- CloseHandle(hFile);
- return NULL;
- }
- //分配信息头大小,并读入数据
- dwInfoSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER);
- pbmi = malloc(dwInfoSize);
- if (NULL == pbmi)
- {
- CloseHandle(hFile);
- return NULL;
- }
- bSuccess = ReadFile(hFile, pbmi, dwInfoSize, &dwBytesRead, NULL);
- if (!bSuccess || (dwBytesRead != dwInfoSize))
- {
- CloseHandle(hFile);
- free(pbmi);
- return NULL;
- }
- //根据BITMAPINFO结构体来创建DIB
- hDib = DibCreateFromInfo(pbmi);
- free(pbmi);
- if (NULL == hDib)
- {
- CloseHandle(hFile);
- return NULL;
- }
- //读取像素位数据,放到DIBSTRUCT结构中pBits字段指向的空间中去
- dwBitsSize = bmfh.bfSize - bmfh.bfOffBits;
- bSuccess = ReadFile(hFile, ((PDIBSTRUCT)hDib)->pBits, dwBitsSize, &dwBytesRead, NULL);
- CloseHandle(hFile);
- if (!bSuccess || (dwBytesRead != dwBitsSize))
- {
- DibDelete(hDib);
- return NULL;
- }
- return hDib;
- }
- /*----------------------------------------------------------------------------------
- DibFileSave:将DIB Section位图保存到文件中
- -----------------------------------------------------------------------------------*/
- BOOL DibFileSave(HDIB hdib, const TCHAR* szFileName)
- {
- BITMAPFILEHEADER bmfh;
- BITMAPINFO* pbmi;
- BOOL bSuccess;
- DWORD dwTotalSize, dwBytesWritten;
- HANDLE hFile;
- hFile = CreateFile(szFileName, GENERIC_WRITE, , NULL,
- CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (INVALID_HANDLE_VALUE == hFile)
- return FALSE;
- dwTotalSize = DibTotalSize(hdib);
- bmfh.bfType = *(WORD*)"BM";
- bmfh.bfSize = sizeof(BITMAPFILEHEADER) + dwTotalSize;
- bmfh.bfReserved1 = ;
- bmfh.bfReserved2 = ;
- bmfh.bfOffBits = bmfh.bfSize - DibBitsSize(hdib);
- //写入BITMAPFILEHEADER
- bSuccess = WriteFile(hFile, &bmfh, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
- if (!bSuccess || (dwBytesWritten != sizeof(BITMAPFILEHEADER)))
- {
- CloseHandle(hFile);
- DeleteFile(szFileName);
- return FALSE;
- }
- //获取整个紧凑型DIB格式
- pbmi = DibCopyToPackedDib(hdib, FALSE);
- if (NULL == pbmi)
- {
- CloseHandle(hFile);
- DeleteFile(szFileName);
- return FALSE;
- }
- //写入pbmi指定的整个紧凑型DIB
- bSuccess = WriteFile(hFile, pbmi, dwTotalSize, &dwBytesWritten, NULL);
- CloseHandle(hFile);
- free(pbmi);
- if (!bSuccess || (dwBytesWritten != dwTotalSize))
- {
- DeleteFile(szFileName);
- return FALSE;
- }
- return TRUE;
- }
- /*----------------------------------------------------------------------------------
- DibCopyToDdb:更高效的屏幕显示
- -----------------------------------------------------------------------------------*/
- HBITMAP DibCopyToDdb(HDIB hdib, HWND hwnd, HPALETTE hPalette)
- {
- HBITMAP hBitmap;
- BITMAPINFO* pbmi;
- HDC hdc;
- if (!DibIsValid(hdib))
- return NULL;
- if (NULL == (pbmi = DibCopyToInfo(hdib)))
- return NULL;
- hdc = GetDC(hwnd);
- if (hPalette)
- {
- SelectPalette(hdc, hPalette, FALSE);
- RealizePalette(hdc);
- }
- hBitmap = CreateDIBitmap(hdc, DibInfoHeaderPtr(hdib), CBM_INIT,
- DibBitsPtr(hdib), pbmi, DIB_RGB_COLORS);
- ReleaseDC(hwnd, hdc);
- free(pbmi);
- return hBitmap;
- }
- /*----------------------------------------------------------------------------------
- DibFlipHorizontal:调用没有优化的DibSetPixel和DibGetPixel
- ----------------------------------------------------------------------------------*/
- HDIB DibFlipHorizontal(HDIB hdibSrc)
- {
- HDIB hdibDst;
- int cx, cy, x, y;
- if (!DibIsAddressable(hdibSrc))
- return NULL;
- if (NULL == (hdibDst = DibCopy(hdibSrc, FALSE)))
- return NULL;
- cx = DibWidth(hdibSrc);
- cy = DibHeight(hdibSrc);
- for (x = ; x < cx; x++)
- for (y = ; y < cy; y++)
- {
- DibSetPixel(hdibDst, x, cy - - y, DibGetPixel(hdibSrc, x, y));
- }
- return hdibDst;
- }
- /*----------------------------------------------------------------------------------
- DibRotateRight:调用优化过的DibSetPixelx和DibGetPixelx
- ----------------------------------------------------------------------------------*/
- HDIB DibRotateRight(HDIB hdibSrc)
- {
- HDIB hdibDst;
- int cx, cy, x, y;
- if (!DibIsAddressable(hdibSrc))
- return NULL;
- if (NULL == (hdibDst = DibCopy(hdibSrc, TRUE)))
- return NULL;
- cx = DibWidth(hdibSrc);
- cy = DibHeight(hdibSrc);
- switch (DibBitCount(hdibSrc))
- {
- case :
- for (x = ; x < cx; x++)
- for (y = ; y < cy; y++)
- {
- DibSetPixel1(hdibDst, cy - - y, x, DibGetPixel1(hdibSrc, x, y)); //坐标旋转
- }
- break;
- case :
- for (x = ; x < cx; x++)
- for (y = ; y < cy; y++)
- {
- DibSetPixel4(hdibDst, cy - - y, x, DibGetPixel4(hdibSrc, x, y));
- }
- break;
- case :
- for (x = ; x < cx; x++)
- for (y = ; y < cy; y++)
- {
- DibSetPixel8(hdibDst, cy - - y, x, DibGetPixel8(hdibSrc, x, y));
- }
- break;
- case :
- for (x = ; x < cx; x++)
- for (y = ; y < cy; y++)
- {
- DibSetPixel16(hdibDst, cy - - y, x, DibGetPixel16(hdibSrc, x, y));
- }
- break;
- case :
- for (x = ; x < cx; x++)
- for (y = ; y < cy; y++)
- {
- DibSetPixel24(hdibDst, cy - - y, x, DibGetPixel24(hdibSrc, x, y));
- }
- break;
- case :
- for (x = ; x < cx; x++)
- for (y = ; y < cy; y++)
- {
- DibSetPixel32(hdibDst, cy - - y, x, DibGetPixel32(hdibSrc, x, y));
- }
- break;
- }
- return hdibDst;
- }
第16章 调色板管理器_16.4 一个DIB位图库的实现(1)的更多相关文章
- 第16章 调色板管理器_16.4 一个DIB位图库的实现(2)
//接上一篇 //DibPal.h /*----------------------------------------------------------------- DIBPAL.H heade ...
- 第15章 上下文管理器和else块
#<流流畅的Python>第15章 上下文管理器和else块 #15.1 先做这个,再做那个:if语句之外的else块 #else子句不仅能在if语句中使用,还能在for.while和tr ...
- 【Ubuntu 16】显示管理器lightdm
lightdm是一个全新的轻量级的显示管理器,在Ubuntu16.04上面已经使用. 从图形界面进入到命令行界面 systemctl disable lightdm.service 从命令行进入到图形 ...
- 流畅的python第十五章上下文管理器和else块学习记录
with 语句和上下文管理器for.while 和 try 语句的 else 子句 with 语句会设置一个临时的上下文,交给上下文管理器对象控制,并且负责清理上下文.这么做能避免错误并减少样板代码, ...
- 第4章 URL管理器和实现方法
URL管理器:管理待抓取URL集合和已抓取URL集合 -- 防止重复抓取.防止循环抓取 URL需要支持哪些功能: 添加新URL到待爬取集合中.判断待添加URL是否在容器中,判断是否还有待爬取URL,获 ...
- 转:OGRE场景管理器介绍
一个场景代表在虚拟世界中显示的物品.场景可以包括静态几何体(比如地形或者室内),模型(比如树.椅子等),光和摄像机.场景有下面种类.室内场景:可能由走廊.有家具的屋子和挂着装饰品的墙组成.室外场景:可 ...
- 【java】浅析java组件中的布局管理器
这篇博文笔者介绍一下java组件中,常用的布局管理器.java组件中的布局方式有好几十种,所有的这些布局管理器都实现了java.awt.LayoutManager接口.接下来笔者介绍一下常用的5种布局 ...
- yum 软件管理器
yum软件管理器 yum是一个强大的软件包管理器,能够自动解决安装时rpm包之间的依赖关系. 一.使用yum管理软件包 1.使用命令 yum help 查看使用方法 [root@majinhai ~] ...
- [Qt Creator 快速入门] 第4章 布局管理
第3章讲述了一些窗口部件,当时往界面上拖放部件时都是随意放置的,这对于学习部件的使用没有太大的影响,但是,对于一个完善的软件,布局管理却是必不可少的. 无论是想要界面中部件有一个很整齐的排列,还是想要 ...
随机推荐
- javascript --- Function模式
回调函数 在javascript中,当一个函数A作为另外一个函数B的其中一个参数时,则称A函数为回调函数,即A可以在函数B的运行周期内执行(开始,中间,结束). 举例来说,有一个函数用于生成node. ...
- 读jQuery源码 - Deferred
Deferred首次出现在jQuery 1.5中,在jQuery 1.8之后被改写,它的出现抹平了javascript中的大量回调产生的金字塔,提供了异步编程的能力,它主要服役于jQuery.ajax ...
- linux系统免密码登陆
有两台机器,系统都是CentOS6.5,IP分别为192.168.2.150,192.168.2.151.现在150需要SSH免密码登陆151. 在150上面执行命令,当前登录用户是root: # s ...
- [原] SharePoint 2010 WebPart与Google地图系列 一:创建显示地图的WebPart
摘要: 作为信息化先驱的产品SharePoint 2010竟然对GIS相关技术支持如此有限,试问现在哪个企业没有大量的项目需要结合Google地图来进行开发,单纯地从Google Javascript ...
- Warning: Attempt to present on whose view is not in the window hierarchy!
当我想从一个VC跳转到另一个VC的时候,一般会用 - (void)presentViewController:(UIViewController *)viewControllerToPresent a ...
- 体验最火的敏捷——SCRUM(厦门,2014.1.4)
1.概述SCRUM是当前最火的一种敏捷开发方法,有用户故事.冲刺.燃尽图等很多很酷的玩法,有牛B的产品负责人.SCRUM Master,有超强的自组织团队.本沙龙将为您展现当前最火最酷的敏捷开发方法! ...
- WPF学习之路(十二)控件(Range控件)
ProgressBar 进度条,主要属性:Minimum\Maximun\Value, IsIndeterminate为True时,进度条会循环运转 <Grid> <Grid.Row ...
- TypeId和IidManager关系
IidInformation结构 数据类型 名字 string name TypeId::hash_t hash uint16_t parent string groupName size_t siz ...
- 按要求编写Java应用程序。 (1)建立一个名叫Cat的类: 属性:姓名、毛色、年龄 行为:显示姓名、喊叫 (2)编写主类: 创建一个对象猫,姓名为“妮妮”,毛色为“灰色”,年龄为2岁,在屏幕上输 出该对象的毛色和年龄,让该对象调用显示姓名和喊叫两个方法。
package zuoye; public class Cat { String name="妮妮"; String color="灰色"; int age=1 ...
- jquery最常用的几个方法。
jquery使用手册:http://www.eduyo.com/doc/jquery/cheatsheet.html addClass 样式: <style> .textRed { col ...