�������� Linux Tags
16. ��ɫ�̹�����
������256����ɫ����ʲô�أ������ԣ�Ҫ��ʾ��ʵ�����ͼ�񣬽�16����ɫ�Dz����ģ�����Ҫʹ����ǧ������������ɫ��256����ɫλ��м�״̬���ǵģ���256����ɫ����ʾ��ʵ�����ͼ���㹻�ˣ�����Ҫ�����ض���ͼ����ָ����Щ��ɫ������ζ����ҵϵͳ���ܼ򵥵�ѡ�񡸱�׼��ϵ�е�256����ɫ����ϣ�����Ƕ�ÿ��Ӧ�ó�ʽ�����������ɫ��
�����Windows��ɫ�̹�������Ҫ�漰��ȫ�����ݡ������ָ����ʽ��8λԪ��ʾģʽ��ִ��ʱ����Ҫ����ɫ�����֪����ʽ�϶�������8λԪ��ʾģʽ��ִ�У���ô��Ҳ����Ҫʹ�õ�ɫ�̹���������������춲����˵���ͼ��һЩϸ�ڣ����Ա��»��ǰ�����Ҫ��Ѷ�ġ�
ʹ�õ�ɫ��
��
��ͳ�Ͻ�����ɫ���ǻ������������ɫ�İ��ӡ������Ҳ����ָ�����ڻæ»ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ê¹ï¿½Ãµï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½É«ï¿½ï¿½ï¿½Úµï¿½ï¿½ï¿½Í¼ï¿½ï¿½ï¿½Ð£ï¿½ï¿½ï¿½É«ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Í¼ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½è±¸ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ñ¶ï¿½ï¿½Ê¾ï¿½ï¿½ï¿½ï¿½ï¿½Ï¿ï¿½ï¿½Ãµï¿½ï¿½ï¿½É«ï¿½ï¿½Î§ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ò²ï¿½ï¿½ï¿½ï¿½Ö¸Ö§Ô®256ɫģʽ����ʾ���ϵĶ��ձ���
��ƵӲ��
��
��ʾ���ϵĵ�ɫ�̶��ձ�������������ͼ��ʾ��
��
��8λԪ��ʾģʽ�У�ÿ��ͼ��ռ8λԪ��ͼ��ֵ��ѯ����256RGBֵ�Ķ��ձ���λַ����ЩRGBֵ��������24λԪ��������Сһ�㣬ͨ����18λԪ��������Ҫ�ĺ졢�̺�����6λԪ����ÿ����ɫ��ֵ�����뵽��λ���ת�������Եõ����͸��������ĺ졢�̺�����������źš�
ͨ�����������������ֵ�������ɫ�̶��ձ��������װ���޹ص��Ӵ����棬����Microsoft Windows������һЩ���š����ȣ�Windows�����ṩ������棬�Ա��ڲ�ֱ�Ӹ���Ӳ�������£�Ӧ�ó�ʽ�Ϳ��Դ�ȡ��ɫ�̹��������ڶ�����������أ���Ϊ���е�Ӧ�ó�ʽ������ͬһ����Ѷ��ʾ��������ͬʱִ�У�����һ��Ӧ�ó�ʽʹ���˵�ɫ�̶��ձ����ܻ�Ӱ��������ʽ��ʹ�á�
��ʱ����Ҫʹ��Windows��ɫ�̹���������Windows 3.0��������ˡ�Windows������256����ɫ�е�20�֣�������Ӧ�ó�ʽ�޸������236�֡�����ijЩ����£�Ӧ�ó�ʽ�����Ըı�256����ɫ�е�254�֣�ֻ�к�ɫ�Ͱ�ɫ���â£ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ò»ï¿½ï¿½ï¿½é·³ï¿½ï¿½ï¿½ï¿½WindowsΪϵͳ������20����ɫ����ʱ��Ϊ20�֡���̬����ɫ�����16-1��ʾ��
��16-1 256����ɫ��ʾģʽ�е�20�ֱ�������ɫ |
ͼ��λԪ | RGBֵ | ��ɫ���� | ͼ��λԪ | RGBֵ | ��ɫ���� |
---|---|---|---|---|---|
00000000 | 00 00 00 | �� | 11111111 | FF FF FF | �� |
00000001 | 80 00 00 | ���� | 11111110 | 00 FF FF | �� |
00000010 | 00 80 00 | ���� | 11111101 | FF 00 FF | ��� |
00000011 | 80 80 00 | ���� | 11111100 | 00 00 FF | �� |
00000100 | 00 00 80 | ���� | 11111011 | FF FF 00 | �� |
00000101 | 80 00 80 | ����� | 11111010 | 00 FF 00 | �� |
00000110 | 00 80 80 | ���� | 11111001 | FF 00 00 | �� |
00000111 | C0 C0 C0 | ���� | 11111000 | 80 80 80 | ���� |
00001000 | C0 DC C0 | ��Ԫ�� | 11110111 | A0 A0 A4 | ���Ի� |
00001001 | A6 CA F0 | ���� | 11110110 | FF FB F0 | ���ɫ |
��256����ɫ��ʾģʽ��ִ��ʱ����Windowsά��ϵͳ��ɫ�̣��˵�ɫ������ʾ���ϵ�Ӳ���ɫ�̶��ձ���ͬ���ڶ���ϵͳ��ɫ�����16-1��ʾ��Ӧ�ó�ʽ����ͨ��ָ�����߼���ɫ�̣�logical palettes�������޸�����236����ɫ������ж��Ӧ�ó�ʽʹ���߼���ɫ�̣���ôWindows�͸���Ӵ��������Ȩ������֪������Ӵ��и�����ʾ�����У�������ʾ�����������Ӵ���ǰ�棩�����ǽ���һЩ�򵥵ķ�����ʽ�����������ι����ġ�
Ҫִ�б����������ֵij�ʽ����������Ҫ����ʾ���л���256ɫģʽ���������ϵ��滬���Ҽ����ӹ��ܱ���ѡ�����ԡ���Ȼ��ѡ���趨��ҳ���ǩ��
��ʾ�ҽ�
��
��ʽ16-1��ʾ��GRAYS1��ʽû��ʹ��Windows��ɫ�̹���������������������ʾ��65���ֽ���Ϊ�Ӻڵ��׵Ķ��ֲ�ɫ�ġ���Դ����
��ʽ16-1 GRAYS1 GRAYS1.C /*--------------------------------------------------------------------------- GRAYS1.C -- Gray Shades (c) Charles Petzold, 1998 -----------------------------------------------------------------------------*/ #include <windows.h> LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("Grays1") ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox ( NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow ( szAppName, TEXT ("Shades of Gray #1"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) { static int cxClient, cyClient ; HBRUSH hBrush ; HDC hdc ; int i ; PAINTSTRUCT ps ; RECT rect ; switch (message) { case WM_SIZE: cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; // Draw the fountain of grays for (i = 0 ; i < 65 ; i++) { rect.left = i * cxClient / 65 ; rect.top = 0 ; rect.right = (i + 1) * cxClient / 65 ; rect.bottom = cyClient ; hBrush = CreateSolidBrush (RGB(min (255, 4 * i), min (255, 4 * i), min (255, 4 * i))) ; FillRect (hdc, &rect, hBrush) ; DeleteObject (hBrush) ; } EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
��WM_PAINTѶϢ�����ڼ䣬��ʽ������65��FillRect��ʽ��ÿ�ζ�ʹ�ò�ͬ�ҽ׽����Ļ�ˢ���ҽ�ֵ��RGBֵ��0,0,0������4,4,4������8,8,8���ȵȣ�ֱ������һ��ֵ��255,255,255��������һ��ֵ����CreateSolidBrush��ʽ�е�min�޼���
�����256ɫ��ʾģʽ��ִ�иó�ʽ�����������Ӻڵ��׵�65�ֻҽף��������Ǽ������û�ɫ��ɫ������ɫֻ�к�ɫ������ɫ��128,128,128��������ɫ��192,192,192���Ͱ�ɫ��������ɫ�ǻ������Щ����ɫ�Ķ�λԪģʽ�������������ʾ�л����֣�����������65�ֻҽ��������Windows����ʹ�û�ɫ��ֻʹ�������ִ�ɫ���������������ʾ����ͼ����ͼ����20�ֱ�׼Windows��ɫ���ơ���ʱ����ͬ����ִ������һ���еij�ʽ��ͬʱ�������˲�ɫ��ҽ�DIB��������һ����ͨ����Windows�ڵ���ͼ�в�ʹ�û�ɫ��
��ʽ16-2��ʾ��GRAYS2��ʽ�ý��ٵ��ⲿ��ʽ����֤�˵�ɫ�̹�����������Ҫ�ĺ�ʽ��ѶϢ��
��ʽ16-2 GRAYS2 GRAYS2.C /*--------------------------------------------------------------------------- GRAYS2.C -- Gray Shades Using Palette Manager (c) Charles Petzold, 1998 -----------------------------------------------------------------------------*/ #include <windows.h> LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("Grays2") ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; if (! RegisterClass (&wndclass)) { MessageBox ( NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow ( szAppName, TEXT ("Shades of Gray #2"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) { static HPALETTE hPalette ; static int cxClient, cyClient ; HBRUSH hBrush ; HDC hdc ; int i ; LOGPALETTE * plp ; PAINTSTRUCT ps ; RECT rect ; switch (message) { case WM_CREATE: // Set up a LOGPALETTE structure and create a palette plp = malloc (sizeof (LOGPALETTE) + 64 * sizeof (PALETTEENTRY)) ; plp->palVersion = 0x0300 ; plp->palNumEntries = 65 ; for (i = 0 ; i < 65 ; i++) { plp->palPalEntry[i].peRed = (BYTE) min (255, 4 * i) ; plp->palPalEntry[i].peGreen = (BYTE) min (255, 4 * i) ; plp->palPalEntry[i].peBlue = (BYTE) min (255, 4 * i) ; plp->palPalEntry[i].peFlags = 0 ; } hPalette = CreatePalette (plp) ; free (plp) ; return 0 ; case WM_SIZE: cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; // Select and realize the palette in the device context SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; // Draw the fountain of grays for (i = 0 ; i < 65 ; i++) { rect.left = i * cxClient / 64 ; rect.top = 0 ; rect.right = (i + 1) * cxClient / 64 ; rect.bottom = cyClient ; hBrush = CreateSolidBrush (PALETTERGB( min (255, 4 * i), min (255, 4 * i), min (255, 4 * i))) ; FillRect (hdc, &rect, hBrush) ; DeleteObject (hBrush) ; } EndPaint (hwnd, &ps) ; return 0 ; 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) break ; hdc = GetDC (hwnd) ; SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; UpdateColors (hdc) ; ReleaseDC (hwnd, hdc) ; break ; case WM_DESTROY: DeleteObject (hPalette) ; PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
ͨ����ʹ�õ�ɫ�̹������ĵ�һ�����Ǻ���CreatePalette��ʽ�������߼���ɫ�̡��߼���ɫ�̰�����ʽ����Ҫ��ȫ����ɫ����236����ɫ��GRAYS1��ʽ��WM_CREATEѶϢ�����ڼ䴦������ҵ������ʼ��LOGPALETTE����logical palette���߼���ɫ�̡����ṹ����λ����������ṹ��ָ�괫�ݸ�CreatePalette��ʽ��CreatePalette�����߼���ɫ�̵Ĵ��ţ������˴��Ŵ����ھ�̬����hPalette�С�
LOGPALETTE�ṹ�������£�
typedef struct { WORD palVersion ; WORD palNumEntries ; PALETTEENTRY palPalEntry[1] ; } LOGPALETTE, * PLOGPALETTE ;
��һ����λͨ����Ϊ0x0300����ʾ����Windows 3.0���ڶ�����λ�趨Ϊ��ɫ�̱��е���Ŀ����LOGPALETTE�ṹ�еĵ�������λ��һ��PALETTEENTRY�ṹ�����У��˽ṹҲ��һ����ɫ����Ŀ��PALETTEENTRY�ṹ�������£�
typedef struct { BYTE peRed ; BYTE peGreen ; BYTE peBlue ; BYTE peFlags ; } PALETTEENTRY, * PPALETTEENTRY ;
ÿ��PALETTEENTRY�ṹ��������һ������Ҫ�ڵ�ɫ����ʹ�õ�RGB��ɫֵ��
ע�⣬LOGPALETTE��ֻ�ܶ���һ��PALETTEENTRY�ṹ�����С�����ҪΪLOGPALETTE�ṹ�͸��ӵ�PALETTEENTRY�ṹ�����㹻��ļ�����ռ䡣GRAYS2��Ҫ65�ֻҽף������ΪLOGPALETTE�ṹ��64�����ӵ�PALETTEENTRY�ṹ�������㹻��ļ�����ռ䡣GRAYS2��palNumEntries��λ�趨Ϊ65��Ȼ���0��64��Ȧ������ҽ׵ȼ���һ���ǻ�Ȧ������4������������255�������ṹ�е�peRed��peGreen��peBlue��λ�趨Ϊ�˻ҽ׵ȼ���peFlags��λ��Ϊ0����ʽ��ָ�������������ָ�괫�ݸ�CreatePalette����һ����̬�����д���õ�ɫ�̴��ţ�Ȼ���ͷż����塣
�߼���ɫ����GDI�������ʽӦ��ɾ�����ǽ����������߼���ɫ�̡�WndProc͸����WM_DESTROYѶϢ�����ڼ����DeleteObject����ϸ��ɾ�����߼���ɫ�̡�
ע���߼���ɫ���Ƕ�����װ�����ݡ�������ʹ��֮ǰ������ȷ������ѡ��װ�����ݡ���WM_PAINTѶϢ�����ڼ䣬SelectPalette���߼���ɫ��ѡ��װ�����ݡ����˺��е������������⣬�˺�ʽ��SelectObject��ʽ���ơ�ͨ����������������ΪFALSE�����SelectPalette�ĵ�����������ΪTRUE����ô��ɫ�̽�ʼ���ǡ�������ɫ�̡�������ζ�����������г�ʽ�������˸��Եĵ�ɫ��֮�ᣬ�õ�ɫ�̲ſ��Ի����λ�ϵͳ��ɫ���е�һ��δʹ����Ŀ��
���κ�ʱ��ֻ��һ���߼���ɫ����ѡ��װ�����ݡ���ʽ������ǰһ��ѡ��װ�����ݵ��߼���ɫ�̴��š������ϣ�������߼���ɫ������ѡ��װ�����ݣ�����Դ���˴��š�
ͨ������ɫӳ�䵽ϵͳ��ɫ�̣�RealizePalette��ʽʹWindows��װ�������С����֡��߼���ɫ�̣���ϵͳ��ɫ��������ʾ��ʵ�ʵ�ʵ�ʵ�ɫ�����Ӧ��ʵ�ʹ����ڴ˺�ʽ�����ڼ���С�Windows����������к�ʽ���Ӵ��ǻ�Ļ��Ƿǻ�ģ��������ܽ�ϵͳ��ɫ���Ѹı�֪ͨ�������Ӵ������ǽ���Ҫ˵��һ��֪ͨ�ij��򣩡�
����һ��GRAYS1������RGB�޼���ָ����ɫ��ˢ����ɫ��RGB�޼�����һ��32λԪ������������COLORREFֵ�������и�λԪ����0��3����λԪ���Ǻ졢�̺��������ȡ�
ʹ��Windows��ɫ�̹������ij�ʽ���Լ���ʹ��RGB��ɫֵ��ָ����ɫ����������ЩRGB��ɫֵ�����ܴ�ȡ�߼���ɫ���еĸ�����ɫ�����ǵ�������û��ʹ�õ�ɫ�̹�������ͬ��Ҫ���߼���ɫ����ʹ�ø��ӵ���ɫ����Ҫ�õ�PALETTERGB�޼�������COLORREFֵ�ĸ�λԪ����Ϊ2������0���⣬����ɫ��RGB����ɫ��RGB��ɫ�����ơ�
��������Ҫ�Ĺ���
���磬��GRAYS2�д���WM_PAINT�ڼ䣬����ѡ���������߼���ɫ��֮�ᣬ�����ͼ��ʾ��ɫ������ʾ�ҽס���������RGB��ɫֵ��ѡ�����߼���ɫ���е���ɫ��
ע�⣬GRAYS2�Ӳ������Ѷ��ʾ������ʽ�Ƿ�֧Ԯ��ɫ�̹�����ʽ���ڲ�֧Ԯ��ɫ�̹�����ʽ����ʾģʽ�������з�256����ɫ����ʾģʽ����ִ��GRAYS2ʱ��GRAYS2�Ĺ�����GRASY1��ͬ��
��ɫ����Ѷ
��
�����ʽ���߼���ɫ����ָ��һ����ɫ������ɫ����20�ֱ�����ɫ֮һ����ôWindows�����߼���ɫ����Ŀӳ�������ɫ�����⣬�����������Ӧ�ó�ʽ�������ǵ��߼���ɫ����ָ����ͬһ����ɫ����ô��ЩӦ�ó�ʽ������ϵͳ��ɫ����Ŀ����ʽ����ͨ����PALETTEENTRY�ṹ��peFlags��λָ��Ϊ����PC_NOCOLLAPSE�����Ը��ڶ�״̬�������������ܵı����PC_EXPLICIT�������ʾϵͳ��ɫ�̣���PC_RESERVED����춵�ɫ�̶��������ҽ��ڱ��µ�����չʾ��������ǣ���
Ҫ������֯ϵͳ��ɫ�̣�Windows��ɫ�̹����������������͸����Ӵ���ѶϢ��
��һ����QM_QUERYNEWPALETTE�������Ӵ��ʱ����ѶϢ���͸����Ӵ��������ʽ�������Ӵ��ϻæ»Ê±Ê¹ï¿½ï¿½ï¿½Ëµï¿½É«ï¿½Ì¹ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ë´¦ï¿½ï¿½ï¿½ï¿½Ñ¶Ï¢ï¿½ï¿½GRAYS2չʾ�������������ʽ���װ�����ݴ��ţ���ѡ����ɫ�̣�����RealizePalette��Ȼ��ʹ�Ӵ�ʧЧ�Բ���WM_PAINTѶϢ������������߼���ɫ�̣����Ӵ�ѶϢ������ʽ�Ӹ�ѶϢ����TRUE�����ò´«»ï¿½FALSE��
��ϵͳ��ɫ�̸ij���WM_QUERYNEWPALETTEѶϢ�Ľ����ͬʱ��Windows��WM_PALETTECHANGEDѶϢ���͸���Ŀǰ����Ӵ�����������ֹ�����Ӵ������������Ӵ���������ǰ̨�Ӵ�������Ȩ�����ݸ��Ӵ�ѶϢ������ʽ��wParamֵ�ǻ�Ӵ��Ĵ��š�ֻ�е�wParam����춳�ʽ���Ӵ�����ʱ��ʹ�õ�ɫ�̹������ij�ʽ�Żᴦ����ѶϢ��
ͨ�����ڴ���WM_PALETTECHANGEDʱ��ʹ���Զ���ɫ�̵��κγ�ʽ������SelectPalette��RealizePalette���������Ӵ���ѶϢ�����ڼ����RealizePaletteʱ��Windows���ȼ���߼���ɫ���е�RGB��ɫ�Ƿ��������뵽ϵͳ��ɫ���е�RGB��ɫ��ƥ�䡣���������ʽ��Ҫ��ͬ����ɫ����ô��������ʽ�͹�ͬʹ��һ��ϵͳ��ɫ����Ŀ����������Windows���δʹ�õ�ϵͳ��ɫ����Ŀ���������ʹ�ã����߼���ɫ���е���ɫ��20�ֱ�����Ŀӳ�䵽�������ɫ��
��������ij�ʽ�ǻʱ��ʾ�������ۣ���ô�����ش���WM_PALETTECHANGEDѶϢ��������������ѡ��GRAYS2��ʾ����֮һ���ڴ���WM_QUERYNEWPALETTEѶϢʱ�������װ�����ݣ�ѡ����ɫ�̣�Ȼ�����RealizePalette����ʱ�Ϳ����ڴ���WM_QUERYNEWPALETTEʱ����InvalidateRect�ˡ��෴�أ�GRAYS2����UpdateColors�������ʽͨ�������»����Ӵ�����Ч��ͬʱ���ı��Ӵ���ͼ�ص�ֵ������������ǰ����ɫ��
ʹ�õ�ɫ�̹������������ʽ������WM_QUERYNEWPALETTE��WM_PALETTECHANGEDѶϢ��GRAYS2����ʾ�ķ�����������
��ɫ����������
��
��ʽ16-3��ʾ��GRAYS3��ʽ��GRAYS2�dz����ƣ�ֻ���ڴ���WM_PAINT�ڼ�ʹ���˺���PALETTEINDEX�ľ޼���������PALETTERGB��
��ʽ16-3 GRAYS3 GRAYS3.C /*--------------------------------------------------------------------------- GRAYS3.C -- Gray Shades Using Palette Manager (c) Charles Petzold, 1998 -----------------------------------------------------------------------------*/ #include <windows.h> LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("Grays3") ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox ( NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow ( szAppName, TEXT ("Shades of Gray #3"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) { static HPALETTE hPalette ; static int cxClient, cyClient ; HBRUSH hBrush ; HDC hdc ; int i ; LOGPALETTE * plp ; PAINTSTRUCT ps ; RECT rect ; switch (message) { case WM_CREATE: // Set up a LOGPALETTE structure and create a palette plp = malloc (sizeof (LOGPALETTE) + 64 * sizeof (PALETTEENTRY)) ; plp->palVersion = 0x0300 ; plp->palNumEntries = 65 ; for (i = 0 ; i < 65 ; i++) { plp->palPalEntry[i].peRed = (BYTE) min (255, 4 * i) ; plp->palPalEntry[i].peGreen = (BYTE) min (255, 4 * i) ; plp->palPalEntry[i].peBlue = (BYTE) min (255, 4 * i) ; plp->palPalEntry[i].peFlags = 0 ; } hPalette = CreatePalette (plp) ; free (plp) ; return 0 ; case WM_SIZE: cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; // Select and realize the palette in the device context SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; // Draw the fountain of grays for (i = 0 ; i < 65 ; i++) { rect.left = i * cxClient / 64 ; rect.top = 0 ; rect.right = (i + 1) * cxClient / 64 ; rect.bottom = cyClient ; hBrush = CreateSolidBrush (PALETTEINDEX (i)) ; FillRect (hdc, &rect, hBrush) ; DeleteObject (hBrush) ; } EndPaint (hwnd, &ps) ; return 0 ; case WM_QUERYNEWPALETTE: if (!hPalette) return FALSE ; hdc = GetDC (hwnd) ; SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; InvalidateRect (hwnd, NULL, FALSE) ; ReleaseDC (hwnd, hdc) ; return TRUE ; case WM_PALETTECHANGED: if (!hPalette || (HWND) wParam == hwnd) break ; hdc = GetDC (hwnd) ; SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; UpdateColors (hdc) ; ReleaseDC (hwnd, hdc) ; break ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
����ɫ�̡���������ɫ��ͬ춵�ɫ��RGB��ɫ�����λԪ����1������λԪ���ֵ��Ŀǰ��װ��������ѡ��ġ��߼���ɫ���е���������GRAYS3�У��߼���ɫ����65����Ŀ�������Щ��Ŀ��������0��64��ֵ
PALETTEINDEX (0)
ָ��ɫ��
PALETTEINDEX (32)
ָ��ɫ����
PALETTEINDEX (64)
ָ��ɫ��
��ΪWindows����Ҫִ�������ɫ������������ʹ�õ�ɫ��������ʹ��RGBֵ����Ч��
��ѯ��ɫ��֧Ԯ
��
���������׵���֤����Windows��16λԪ��24λԪ��ʾģʽ��ִ��ʱ��GRAYS2��GRAYS3��ʽִ�����á�������ijЩ����£�Ҫʹ�õ�ɫ�̹�������WindowsӦ�ó�ʽ����Ҫ��ȷ��װ��������ʽ�Ƿ�֧Ԯ������ʱ�������Ժ���GetDeviceCaps��������Ѷ��ʾ��װ�����ݴ��ź�PASTERCAPS��Ϊ��������ʽ��������һϵ�������ɵ�������ͨ���ڴ���ֵ�ͳ���RC_PALETTE֮��ִ��λԪ����������֧Ԯ�ĵ�ɫ�̣�
RC_PALETTE & GetDeviceCaps (hdc, RASTERCAPS)
�����ֵ���㣬����Ѷ��ʾ��װ��������ʽ��֧Ԯ��ɫ�̲��������������֮�£�����GetDeviceCaps������������Ҫ��ĿҲ�ǿ��õġ���ʽ����
GetDeviceCaps (hdc, SIZEPALETTE)
����������ʾ���ϵ�ɫ�̱����ܳߴ硣����ͬʱ��ʾ����ɫ������ͬ����Ϊ��ɫ�̹�����ֻ���ÿͼ��8λԪ����Ѷ��ʾģʽ�����Դ�ֵ����256��
��ʽ����
GetDeviceCaps (hdc, NUMRESERVED)
�����ڵ�ɫ�̱��е���ɫ�����ñ���װ��������ʽΪϵͳ�����ģ���ֵ��20�������е�ɫ�̹���������Щֻ��WindowsӦ�ó�ʽ��256ɫ��ʾģʽ��ʹ�õĴ�ɫ��Ҫʹ�������236����ɫ����ʽ����ʹ�õ�ɫ�̹�������ʽ��
һ��������ĿҲ���ã�
GetDeviceCaps (hdc, COLORRES)
��ֵ���������뵽Ӳ���ɫ�̱���RGB��ɫֵ�����ȣ���λԪ�ƣ�����Щ�ǽ�����λ���ת������λԪ��ijЩ��Ѷ��ʾ��ֻʹ��6λԪADC�����Ը�ֵ��18������ʹ��8λԪ��ADC������ֵ��24��
Windows��ʽע����ɫ�����Ȳ���˲�ȡһЩ�����Ǻ����õġ����磬�������ɫ��������18����ô��ʽ��������Ҫ��128�ֻҽף���Ϊֻ��64����ɢ�Ļҽ׿��á�Ҫ��128�ֻҽ׾Ͳ����ö������Ŀ�����Ӳ���ɫ�̱���
ϵͳ��ɫ��
��
����ǰ�������Windowsϵͳ��ɫ��ֱ������ʾ���ϵ�Ӳ���ɫ�̲�ѯ�������Ȼ����Ӳ���ɫ�̲�ѯ�����ܱ�ϵͳ��ɫ�̵���ɫ�����ȵͣ�����ʽ����ͨ����������ĺ�ʽ�����ϵͳ��ɫ���е�ijЩ��ȫ����RGB��Ŀ��
GetSystemPaletteEntries (hdc, uStart, uNum, &pe) ;
ֻ����ʾ��ģʽ֧Ԯ��ɫ�̲���ʱ���ú�ʽ����ִ�С��ڶ����͵���������������������������ʾ��һ����ɫ����Ŀ�������͵�ɫ����Ŀ��������һ��������ָ��PALETTEENTRY��̬��ָ�ꡣ
�������ڼ��������ʹ�øú�ʽ����ʽ���Զ���PALETTEENTRY�ṹ���£�
PALETTEENTRY pe ;
Ȼ��ɰ�����ķ�����κ���GetSystemPaletteEntries��
GetSystemPaletteEntries (hdc, i, 1, &pe) ;
���е�i��0��ij��ֵ����ֵС춴�GetDeviceCaps������SIZEPALETTE����255�����ص�ֵ�����ߣ���ʽҪ������е�ϵͳ��ɫ����Ŀ������ͨ������ָ��PALETTEENTRY�ṹ��ָ�꣬Ȼ�����������㹻�ļ�����飬�Դ������ɫ�̴�Сָ��ͬ�����PALETTEENTRY�ṹ��
GetSystemPaletteEntries��ʽȷʵ����������Ӳ���ɫ�̱���ϵͳ��ɫ���е���Ŀ��ͼ��ֵ���ӵ�˳�����У���Щֵ��춱�ʾ��Ѷ��ʾ�������е���ɫ���ҽ��򵥵�����һ�¾���������
������ɫ�̺�ʽ
��
������ǰ�濴����Windows��ʽ�ܹ��ı�ϵͳ��ɫ�̣���ֻ�Ǽ�Ӹı䣺��һ�������߼���ɫ�̣����������dz�ʽҪʹ�õ�RGB��ɫֵ���С�CreatePalette��ʽ���ᵼ��ϵͳ��ɫ�̻�����ʾ����ɫ�̱����κα仯���߼���ɫ�̱������κ����鷢��֮ǰ��ѡ��װ�����ݲ����֡�
��ʽ����ͨ������
GetPaletteEntries (hPalette, uStart, uNum, &pe) ;
����ѯ�߼���ɫ���е�RGB��ɫֵ�������԰�ʹ��GetSystemPaletteEntries�ķ�����ʹ�ô˺�ʽ������Ҫע�⣬��һ���������߼���ɫ�̵Ĵ��ţ�������װ�����ݵĴ��š�
�����߼���ɫ�����ᣬ�����ı����е�ֵ����Ӧ��ʽ�ǣ�
SetPaletteEntries (hPalette, uStart, uNum, &pe) ;
���⣬��ס���д˺�ʽ������ϵͳ��ɫ�̵��κα仯����ʹĿǰ��ɫ��ѡ����װ�����ݡ��˺�ʽҲ���ı��߼���ɫ�̵ijߴ硣Ҫ�ı��߼���ɫ�̵ijߴ磬��ʹ��ResizePalette��
����ĺ�ʽ����RGB��ɫ����ֵ��Ϊ����IJ����������������ظ��߼���ɫ�̣����߼���ɫ���������ӽ���RGB��ɫֵ���Ӧ��
iIndex = GetNearestPaletteIndex (hPalette, cr) ;
�ڶ���������COLORREFֵ�����ϣ���Ļ�������GetPaletteEntries�Ϳ��Ի���߼���ɫ����ʵ�ʵ�RGB��ɫֵ��
�����ʽ��8λԪ��ʾģʽ����Ҫ���236���Զ���ɫ������Ժ���GetSystemPaletteUse����������ʽ�趨254���Զ���ɫ��ϵͳ��������ɫ�Ͱ�ɫ����������ʽ������󻯳���ȫөĻʱ����������������������һЩϵͳ��ɫ��Ϊ��ɫ�Ͱ�ɫ���Ա�����к͹��ܱ�����Ȼ�ɼ���
λԪӳ���������
��
�ӵ����¿����˽⵽��GDI����ʹ�ò�ͬ�ġ��æ»Ä£Ê½ï¿½ï¿½ï¿½ï¿½Î»ÔªÓ³ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ß²ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½SetROP2�趨�æ»Ä£Ê½ï¿½ï¿½ï¿½ï¿½ï¿½ÐµÄ¡ï¿½2����ʾ�������֮��Ķ�Ԫ��binary��λԪӳ���������ԪλԪӳ�������춴���BitBlt�����ƹ��ܡ���ЩλԪӳ��������������ڻ������ͼ�������ͼ�صĽ�Ϸ�ʽ�����磬�����Ի�һ��ֱ�ߣ��Ա����ϵ�ͼ������ʾ��ͼ�ذ�λԪ���ķ�ʽ���ϡ�
λԪӳ�����������ͼ��λԪ����������λԪ��˳����в������ı��ɫ�̻�Ӱ�쵽��ЩλԪӳ�������λԪӳ������IJ��������ͼ��λԪ������Щͼ��λԪ������ʵ����ɫû�й�����
͸��ִ��GRAYS2��GRAYS3��ʽ�����Լ��Ϳ��Եó�������ۡ������ߴ�ʱ���϶�������ײ��ı߽紩���Ӵ���Windows���÷�ת����ͼ��λԪ��λԪӳ���������ʾ�϶��ߴ�ı߽磬��Ŀ����ʹ�϶��ߴ�߽����ǿɼ��ġ�����GRAYS2��GRAYS3��ʽ�У�����������������任����ɫ����Щ��ɫǡ�����Ӧ춵�ɫ�̱���δʹ�õ���Ŀ�����Ƿ�ת��ʾͼ��λԪ�Ľ����������ɫû�з�ת��ֻ��ͼ��λԪ��ת�ˡ�
�������ڱ�16-1����������һ����20�ֱ�׼������ɫλ�ϵͳ��ɫ�̵Ķ����͵ײ����Ա�λԪӳ������Ľ����Ȼ������Ȼ����һ������ʼ�޸ĵ�ɫ�̣��������滻�˱�����ɫ����ô��ɫ�����λԪӳ������ͱ��û�������ˡ�
Ψһ��֤����λԪӳ��������ú�ɫ�Ͱ�ɫ��������ɫ��ϵͳ��ɫ���еĵ�һ����Ŀ�����е�ͼ��λԪ����Ϊ0��������ɫ���������Ŀ�����е�ͼ��λԪ����Ϊ1������������Ŀ���ܸı䡣�����ҪԤ֪����ɫ����Ͻ���λԪӳ������Ľ����������Ȼ��ϵͳ��ɫ�̱���Ȼ��鿴��ͬͼ��λԪֵ��RGB��ɫֵ��
�鿴ϵͳ��ɫ��
��
��Windows��ִ�еij�ʽ�������߼���ɫ�̣�Ϊʹ�߼���ɫ�̸��õط��������ʹ���߼���ɫ�̵ij�ʽ��Windows����ϵͳ��ɫ�����趨��ɫ����ϵͳ��ɫ�̸�������ʾ����Ӳ����ձ����ݡ��������鿴ϵͳ��ɫ������춵��ʵ�ɫ��Ӧ�ó�ʽ��
��Ϊ���������������ֽ�Ȼ��ͬ�Ĵ�����ʽ�������ҽ�����չʾ������ʽ������ʾϵͳ��ɫ�̵����ݡ�
SYSPAL1��ʽ�����ʽ16-4��ʾ��ʹ����ǰ��������GetSystemPaletteEntries��ʽ��
��ʽ16-4 SYSPAL1 SYSPAL1.C /*--------------------------------------------------------------------------- SYSPAL1.C -- Displays system palette (c) Charles Petzold, 1998 -----------------------------------------------------------------------------*/ #include <windows.h> LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; TCHAR szAppName [] = TEXT ("SysPal1") ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox ( NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow ( szAppName, TEXT ("System Palette #1"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; if (!hwnd) return 0 ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } BOOL CheckDisplay (HWND hwnd) { HDC hdc ; int iPalSize ; hdc = GetDC (hwnd) ; iPalSize = GetDeviceCaps (hdc, SIZEPALETTE) ; ReleaseDC (hwnd, hdc) ; if (iPalSize != 256) { MessageBox (hwnd,TEXT ("This program requires that the video ") TEXT ("display mode have a 256-color palette."), szAppName, MB_ICONERROR) ; return FALSE ; } return TRUE ; } LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) { static int cxClient, cyClient ; static SIZE sizeChar ; HDC hdc ; HPALETTE hPalette ; int i, x, y ; PAINTSTRUCT ps ; PALETTEENTRY pe [256] ; TCHAR szBuffer [16] ; switch (message) { case WM_CREATE: if (!CheckDisplay (hwnd)) return -1 ; hdc = GetDC (hwnd) ; SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ; GetTextExtentPoint32 (hdc, TEXT ("FF-FF-FF"), 10, &sizeChar) ; ReleaseDC (hwnd, hdc) ; return 0 ; case WM_DISPLAYCHANGE: if (!CheckDisplay (hwnd)) DestroyWindow (hwnd) ; return 0 ; case WM_SIZE: cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ; GetSystemPaletteEntries (hdc, 0, 256, pe) ; for (i = 0, x = 0, y = 0 ; i < 256 ; i++) { wsprintf ( szBuffer, TEXT ("%02X-%02X-%02X"), pe[i].peRed, pe[i].peGreen, pe[i].peBlue) ; TextOut (hdc, x, y, szBuffer, lstrlen (szBuffer)) ; if (( x += sizeChar.cx) + sizeChar.cx > cxClient) { x = 0 ; if (( y += sizeChar.cy) > cyClient) break ; } } EndPaint (hwnd, &ps) ; return 0 ; case WM_PALETTECHANGED: InvalidateRect (hwnd, NULL, FALSE) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
��SYSPALϵ���е�������ʽһ�������Ǵ���SIZEPALETTE������GetDeviceCaps����ֵΪ256������SYSPAL1����ִ�С�
ע������SYSPAL1����ʾ����ʲôʱ���յ�WM_PALETTECHANGEDѶϢ����������Ч�ġ��ںϲ�WM_PAINTѶϢ�����ڼ䣬SYSPAL1����GetSystemPaletteEntries������һ����256��PALETTEENTRY�ṹ��������Ϊ������RGBֵ��Ϊ�����ִ���ʾ����ʾ���򡣳�ʽִ��ʱ��ע��20�ֱ�����ɫ��RGBֵ�б��е�ǰ10������10���������16-1��ʾ��ͬ��
��SYSPAL1��ʾ���õ���Ѷʱ������ʵ�ʿ�����256����ɫ��ͬ���Ǿ���SYSPAL2����ҵ�����ʽ16-5��ʾ��
��ʽ16-5 SYSPAL2 SYSPAL2.C /*--------------------------------------------------------------------------- SYSPAL2.C -- Displays system palette (c) Charles Petzold, 1998 ----------------------------------------------------------------------------*/ #include <windows.h> LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; TCHAR szAppName [] = TEXT ("SysPal2") ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox ( NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow ( szAppName, TEXT ("System Palette #2"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; if (!hwnd) return 0 ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } BOOL CheckDisplay (HWND hwnd) { HDC hdc ; int iPalSize ; hdc = GetDC (hwnd) ; iPalSize = GetDeviceCaps (hdc, SIZEPALETTE) ; ReleaseDC (hwnd, hdc) ; if (iPalSize != 256) { MessageBox (hwnd, TEXT ("This program requires that the video ") TEXT ("display mode have a 256-color palette."), szAppName, MB_ICONERROR) ; return FALSE ; } return TRUE ; } LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) { static HPALETTE hPalette ; static int cxClient, cyClient ; HBRUSH hBrush ; HDC hdc ; int i, x, y ; LOGPALETTE * plp ; PAINTSTRUCT ps ; RECT rect ; switch (message) { case WM_CREATE: if (!CheckDisplay (hwnd)) return -1 ; plp = malloc (sizeof (LOGPALETTE) + 255 * sizeof (PALETTEENTRY)) ; plp->palVersion = 0x0300 ; plp->palNumEntries = 256 ; for (i = 0 ; i < 256 ; i++) { plp->palPalEntry[i].peRed = i ; plp->palPalEntry[i].peGreen = 0 ; plp->palPalEntry[i].peBlue = 0 ; plp->palPalEntry[i].peFlags = PC_EXPLICIT ; } hPalette = CreatePalette (plp) ; free (plp) ; return 0 ; case WM_DISPLAYCHANGE: if (!CheckDisplay (hwnd)) DestroyWindow (hwnd) ; return 0 ; case WM_SIZE: cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; for (y = 0 ; y < 16 ; y++) for (x = 0 ; x < 16 ; x++) { hBrush = CreateSolidBrush (PALETTEINDEX (16 * y + x)) ; SetRect (&rect, x * cxClient /16, y * cyClient / 16, (x + 1)` * cxClient / 16,(y+1) * cyClient / 16); FillRect (hdc, &rect, hBrush) ; DeleteObject (hBrush) ; } EndPaint (hwnd, &ps) ; return 0 ; case WM_PALETTECHANGED: if ((HWND) wParam != hwnd) InvalidateRect (hwnd, NULL, FALSE) ; return 0 ; case WM_DESTROY: DeleteObject (hPalette) ; PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
SYSPAL2��WM_CREATEѶϢ�����ڼ佨�����߼���ɫ�̡�������ע�⣺�߼���ɫ�������е�256��ֵ���Ǵ�0��255�ĵ�ɫ������������peFlags��λ��PC_EXPLICIT�����������������ģ����߼���ɫ����Ŀ�Ľϵ�����ָ����һ��Ӳ���ɫ�����������������Ӧ�ó�ʽ��ʾӲ���ɫ�̵����ݡ�����������רΪ����Ҫ��������������Ƶġ�
��WM_PAINTѶϢ�����ڼ䣬SYSPAL2���õ�ɫ��ѡ��װ�����ݲ����������ⲻ������ϵͳ��ɫ�̵��κ����飬����������ʽʹ��PALETTEINDEX�޼���ָ��ϵͳ��ɫ���е���ɫ�����˷�����SYSPAL2��ʾ��256�����Ρ����⣬����ִ�иó�ʽʱ��ע�ⶥ�к͵��е�ǰ10�ֺ���10����ɫ��20�ֱ�����ɫ�����16-1��ʾ������ִ��ʹ���Լ��߼���ɫ�̵ij�ʽʱ����ʾ�͸ı��ˡ�
�������ϲ����SYSPAL2�е���ɫ����ϲ��RGB��ֵ����ô����ڰ��µ�WHATCLR��ʽͬʱִ�С�
SYSPALϵ���еĵ�����ʹ�õļ���������˵������ų��ֵģ����ҿ�ʼ�о�Windows��ɫ�̹�����������ᣬ�ų�������Щ������
��ʵ�ϣ����е�GDI��ʽ��ֱ�ӻ��ӵ�ָ����ɫ��ΪRGBֵ����GDI�ڲ����⽫ת�������Ǹ���ɫ��ص�ͼ��λԪ����ijЩ��ʾģʽ�У����磬16λԪ��24λԪ��ɫģʽ������Щת�����൱ֱ�ӵġ���������ʾģʽ�У�4λԪ��8λԪ��ɫ����������漰��ӽ���ɫ��������
Ȼ����������GDI��ʽ����ֱ��ָ��ͼ��λԪ�е���ɫ����Ȼ�����ַ�ʽ��ʹ�õ���������ʽ�����豸�߶���ء�����̫�����豸�ˣ���������ǿ���ֱ����ʾ��Ѷ��ʾ����ʵ�ʵĵ�ɫ�̶��ձ�����������ʽ��BitBlt��StretchBlt��
��ʽ16-6��ʾ��SYSPAL3��ʽ��ʾ��ʹ��StretchBlt��ʾϵͳ��ɫ������ɫ�ķ�����
��ʽ16-6 SYSPAL3 SYSPAL3.C /*--------------------------------------------------------------------------- SYSPAL3.C -- Displays system palette (c) Charles Petzold, 1998 ----------------------------------------------------------------------------*/ #include <windows.h> LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; TCHAR szAppName [] = TEXT ("SysPal3") ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox ( NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow ( szAppName, TEXT ("System Palette #3"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; if (!hwnd) return 0 ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } BOOL CheckDisplay (HWND hwnd) { HDC hdc ; int iPalSize ; hdc = GetDC (hwnd) ; iPalSize = GetDeviceCaps (hdc, SIZEPALETTE) ; ReleaseDC (hwnd, hdc) ; if (iPalSize != 256) { MessageBox (hwnd,TEXT("This program requires that the video ") TEXT("display mode have a 256-color palette."), szAppName, MB_ICONERROR) ; return FALSE ; } return TRUE ; } LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) { static HBITMAP hBitmap ; static int cxClient, cyClient ; BYTE bits [256] ; HDC hdc, hdcMem ; int i ; PAINTSTRUCT ps ; switch (message) { case WM_CREATE: if (! CheckDisplay (hwnd)) return -1 ; for ( i = 0 ; i < 256 ; i++) bits [i] = i ; hBitmap = CreateBitmap (16, 16, 1, 8, &bits) ; return 0 ; case WM_DISPLAYCHANGE: if (!CheckDisplay (hwnd)) DestroyWindow (hwnd) ; return 0 ; case WM_SIZE: cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; hdcMem = CreateCompatibleDC (hdc) ; SelectObject (hdcMem, hBitmap) ; StretchBlt (hdc, 0, 0, cxClient, cyClient, hdcMem, 0, 0, 16, 16, SRCCOPY) ; DeleteDC (hdcMem) ; EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: DeleteObject (hBitmap) ; PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
��WM_CREATEѶϢ�����ڼ䣬SYSPAL3ʹ��CreateBitmap������16��16��ÿͼ��8λԪ�ĵ���ͼ���ú�ʽ������һ�������ǰ�����ֵ0��255��256λԪ�����С���Щ��256�ֿ��ܵ�ͼ��λԪֵ���ڴ���WM_PAINTѶϢ�ij����У���ʽ���������ͼѡ��������װ�����ݣ���StretchBlt����ʾ��������ʾ����Windows��������ͼ�е�ͼ��λԪ���䵽��Ѷ��ʾ��Ӳ�壬�Ӷ�������Щͼ��λԪ��ȡ��ɫ�̶��ձ��е�256����Ŀ����ʽ����ʾ������������ʹ����WM_PALETTECHANGEDѶϢ��Ч����춶��ձ����κ��޸Ķ�������Ӱ�쵽SYSPAL3����ʾ��
��ɫ�̶���
��
�ڱ��ڵı����п�����������һ�ʣ�����ʼ����өĻ��Χִ�еġ����Գ��ʱ��������ǰ���ܻ�Ϊ֮һ�����ǵģ�������ʹ��Windows��ɫ�̹�������һЩ��������������һ��רҵˮƽ�Ķ�����
ͨ����Windows�µĶ������ǿ�����������ʾһϵ�е���ͼ����ɫ�̶��������ַ����кܴ��������͸����өĻ�ϻ���������Ҫ��ÿ��������ʼ��Ȼ����������ɫ�����ı���Щ�������ɫ�������ǻ�һЩ����өĻ������˵�Dz��ɼ���ͼ���������ַ����Ϳ��Ի�ö���Ч�����������ػ��κζ�������ɫ�̶������ٶ����൱��ġ�
��춵�ɫ�̶���������Ľ�������������ǰ�濴������Щ��ͬ����춶����ڼ�Ҫ�޸ĵ�ÿ��RGB��ɫֵ��PALETTEENTRY�ṹ��peFlags��λ�����趨ΪPC_RESERVED��
ͨ��������������������һ�����ڽ����߼���ɫ��ʱ������peFlags�����Ϊ0��������GDI������߼���ɫ����ͬ������ɫӳ�䵽��ͬ��ϵͳ��ɫ����Ŀ�����磬��������Windows��ʽ�������˰���RGB��Ŀ10-10-10���߼���ɫ�̣���ô��ϵͳ��ɫ�̱��У�Windowsֻ��Ҫһ��10-10-10��Ŀ���������������ʽ�е�һ��ʹ�õ�ɫ�̶����������Ͳ�Ҫ����GDIʹ�õ�ɫ���ˡ���ɫ�̶�����ζ���ٶȷdz��ì£ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ø»ï¿½ï¿½ï¿½ï¿½ï¿½Ò²Ö»ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ù¶È¡ï¿½ï¿½ï¿½Ê¹ï¿½Ãµï¿½É«ï¿½Ì¶ï¿½ï¿½ï¿½ï¿½Ä³ï¿½Ê½ï¿½Þ¸Äµï¿½É«ï¿½ï¿½Ê±ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ó°ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ê½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ê¹GDI����ϵͳ��ɫ�̱���PC_RESERVED��peFlagsֵΪ�����߼���ɫ�̴���ϵͳ��ɫ����Ŀ��
ʹ�õ�ɫ�̶���ʱ��ͨ����������WM_PAINTѶϢ�����ڼ����SelectPalette��RealizePalette��ʹ��PALETTEINDEX�޼���ָ����ɫ���þ޼���һ�����������߼���ɫ�̱���
��춶�����������Ҫͨ���ı��ɫ������ӦWM_TIMERѶϢ��Ҫ�ı��߼���ɫ���е�RGB��ɫֵ����ʹ��һ��PALETTEENTRY�ṹ�����������к�ʽAnimatePalette���˺�ʽ�ٶȺܿ죬��Ϊ��ֻ��Ҫ�ı�ϵͳ��ɫ���Լ���ʾ��Ӳ���ɫ�̱��е���Ŀ��
��������
��
��ʽ16-7��ʾ��BOUNCE��ʽ��Ԫ����������һ����ʽ����ʾ��������Ϊ�˼������������ʾ����Ĵ�С���ò»³ï¿½ï¿½ï¿½ï¿½ï¿½Ô²ï¿½Î¡ï¿½ï¿½ï¿½Îªï¿½ï¿½ï¿½ï¿½ï¿½Ð¼ï¿½ï¿½ï¿½ï¿½ï¿½É«ï¿½Ì¶ï¿½ï¿½ï¿½ï¿½ï¿½Ê½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½PALANIM.C������ɫ�̶���������������һЩͨ�����ݡ�
��ʽ16-7 BOUNCE PALANIM.C /*-------------------------------------------------------------------------- PALANIM.C -- Palette Animation Shell Program s(c) Charles Petzold, 1998 ---------------------------------------------------------------------------*/ #include <windows.h> extern HPALETTE CreateRoutine (HWND) ; extern void PaintRoutine (HDC, int, int) ; extern void TimerRoutine (HDC, HPALETTE) ; extern void DestroyRoutine (HWND, HPALETTE) ; LRESULT CALLBA CK WndProc (HWND, UINT, WPARAM, LPARAM) ; extern TCHAR szAppName [] ; extern TCHAR szTitle [] ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox ( NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow ( szAppName, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; if (!hwnd) return 0 ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } BOOL CheckDisplay (HWND hwnd) { HDC hdc ; int iPalSize ; hdc = GetDC (hwnd) ; iPalSize = GetDeviceCaps (hdc, SIZEPALETTE) ; ReleaseDC (hwnd, hdc) ; if (iPalSize != 256) { MessageBox (hwnd, TEXT ("This program requires that the video ") TEXT ("display mode have a 256-color palette."), szAppName, MB_ICONERROR) ; return FALSE ; } return TRUE ; } LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) { static HPALETTE hPalette ; static int cxClient, cyClient ; HDC hdc ; PAINTSTRUCT ps ; switch (message) { case WM_CREATE: if (!CheckDisplay (hwnd)) return -1 ; hPalette = CreateRoutine (hwnd) ; return 0 ; case WM_DISPLAYCHANGE: if (!CheckDisplay (hwnd)) DestroyWindow (hwnd) ; return 0 ; case WM_SIZE: cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; PaintRoutine (hdc, cxClient, cyClient) ; EndPaint (hwnd, &ps) ; return 0 ; case WM_TIMER: hdc = GetDC (hwnd) ; SelectPalette (hdc, hPalette, FALSE) ; TimerRoutine (hdc, hPalette) ; ReleaseDC (hwnd, hdc) ; return 0 ; 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) break ; hdc = GetDC (hwnd) ; SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; UpdateColors (hdc) ; ReleaseDC (hwnd, hdc) ; break ; case WM_DESTROY: DestroyRoutine (hwnd, hPalette) ; PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
BOUNCE.C /*-------------------------------------------------------------------------- BOUNCE.C -- Palette Animation Demo (c) Charles Petzold, 1998 ----------------------------------------------------------------------------*/ #include <windows.h> #define ID_TIMER 1 TCHAR szAppName [] = TEXT ("Bounce") ; TCHAR szTitle [] = TEXT ("Bounce: Palette Animation Demo") ; static LOGPALETTE * plp ; HPALETTE CreateRoutine (HWND hwnd) { HPALETTE hPalette ; int i ; plp = malloc (sizeof (LOGPALETTE) + 33 * sizeof (PALETTEENTRY)) ; plp->palVersion = 0x0300 ; plp->palNumEntries = 34 ; for (i = 0 ; i < 34 ; i++) { plp->palPalEntry[i].peRed = 255 ; plp->palPalEntry[i].peGreen = (i == 0 ? 0 : 255) ; plp->palPalEntry[i].peBlue = (i == 0 ? 0 : 255) ; plp->palPalEntry[i].peFlags = (i == 33 ? 0 : PC_RESERVED) ; } hPalette = CreatePalette (plp) ; SetTimer (hwnd, ID_TIMER, 50, NULL) ; return hPalette ; } void PaintRoutine (HDC hdc, int cxClient, int cyClient) { HBRUSH hBrush ; int i, x1, x2, y1, y2 ; RECT rect ; // Draw window background using palette index 33 SetRect (&rect, 0, 0, cxClient, cyClient) ; hBrush = CreateSolidBrush (PALETTEINDEX (33)) ; FillRect (hdc, &rect, hBrush) ; DeleteObject (hBrush) ; // Draw the 33 balls SelectObject (hdc, GetStockObject (NULL_PEN)) ; for (i = 0 ; i < 33 ; i++) { x1 = i * cxClient / 33 ; x2 = (i + 1)* cxClient / 33 ; if (i < 9) { y1 = i * cyClient / 9 ; y2 = (i + 1) * cyClient / 9 ; } else if (i < 17) { y1 = (16 - i) * cyClient / 9 ; y2 = (17 - i) * cyClient / 9 ; } else if (i < 25) { y1 = (i - 16) * cyClient / 9 ; y2 = (i - 15) * cyClient / 9 ; } else { y1 = (32 - i) * cyClient / 9 ; y2 = (33 - i) * cyClient / 9 ; } hBrush = CreateSolidBrush (PALETTEINDEX (i)) ; SelectObject (hdc, hBrush) ; Ellipse (hdc, x1, y1, x2, y2) ; DeleteObject (SelectObject (hdc, GetStockObject (WHITE_BRUSH))) ; } return ; } void TimerRoutine (HDC hdc, HPALETTE hPalette) { static BOOL bLeftToRight = TRUE ; static int iBall ; // Set old ball to white plp->palPalEntry[iBall].peGreen = 255 ; plp->palPalEntry[iBall].peBlue = 255 ; iBall += (bLeftToRight ? 1 : -1) ; if ( iBall == (bLeftToRight ? 33 : -1)) { iBall = (bLeftToRight ? 31 : 1) ; bLeftToRight ^= TRUE ; } // Set new ball to red plp->palPalEntry[iBall].peGreen = 0 ; plp->palPalEntry[iBall].peBlue = 0 ; // Animate the palette AnimatePalette (hPalette, 0, 33, plp->palPalEntry) ; return ; } void DestroyRoutine (HWND hwnd, HPALETTE hPalette) { KillTimer (hwnd, ID_TIMER) ; DeleteObject (hPalette) ; free (plp) ; return ; }
����Windows���֧Ԯ��ɫ�̵���ʾģʽ�£������ɫ�̶��������ܹ�������ˣ�PALANIM.Cͨ������CheckDisplay��ʽ����SYSPAL��ʽ�еĺ�ʽ��ͬ������ʼ����WM_CREATE��
PALANIM.C����BOUNCE.C�е��ĸ���ʽ����WM_CREATEѶϢ�����ڼ����CreateRoutine����BOUNCE����춽����߼���ɫ�̣�����WM_PAINTѶϢ�����ڼ����PaintRoutine����WM_TIMERѶϢ�����ڼ����TimerRoutine����WM_DESTROYѶϢ�����ڼ����DestroyRoutine����BOUNCE�������������ں���PaintRoutine��TimerRoutine֮ǰ��PALANIM.C���װ�����ݣ�������ѡ���߼���ɫ�̡��ں���PaintRoutine֮ǰ����Ҳ���ֵ�ɫ�̡�PALANIM.C����TimerRoutine����AnimatePalette������AnimatePalette��Ҫ��װ��������ѡ���ɫ�̣���������Ҫ����RealizePalette��
BOUNCE�е��򰴡�W��·������ʾ������������������ʾ���򱳾��ǰ�ɫ�����Ǻ�ɫ���κ�ʱ�򣬶�������33�����ص���λ��֮һ����������Ҫ34����ɫ����Ŀ��һ����춱���������33����춲�ͬλ�õ�����CreateRoutine�У�BOUNCE��ʼ��PALETTEENTRY�ṹ��һ�����У�����һ����ɫ����Ŀ�����������Ͻǵ�λ�ö�Ӧ���趨Ϊ��ɫ���������趨Ϊ��ɫ��ע�⣬��춳����������������Ŀ��peFlags��λ���趨ΪPC_RESERVED�������������һ����ɫ����Ŀ����BOUNCEͨ����Windows��ʱ���ļ���趨Ϊ50��������ֹCreateRoutine��
BOUNCE��PaintRoutine������еĻæ»ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ó´ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ò»ï¿½ï¿½Êµï¿½Ä»ï¿½Ë¢ï¿½Íµï¿½É«ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½33��ָ������ɫ�����ơ�33�������ɫ�����ݴ�0��32�ĵ�ɫ����������ɫ����BOUNCE��һ������ʾ�����ڻæ»Ê±ï¿½ï¿½0�ĵ�ɫ������ӳ��ɺ�ɫ��������ɫ������ӳ�䵽��ɫ���⵼������������Ͻǡ�
��WndProc����WM_TIMERѶϢ������TimerRoutineʱ�������ͷ����ˡ�TimerRoutineͨ������AnimatePalette���������﷨���£�
AnimatePalette (hPalette, uStart, uNum, &pe) ;
���У���һ�������ǵ�ɫ�̴��ţ�����һ��������ָ�����е�ָ�꣬��������һ������PALETTEENTRY�ṹ��ɡ��ú�ʽ�ı��߼���ɫ���д�uStart��Ŀ��uNum��Ŀ֮���������Ŀ���߼���ɫ�����µ�uStart��Ŀ��PALETTEENTRY�ṹ�еĵ�һ����Ա�����ģ�uStart�����ǽ���Ôʼ�߼���ɫ�̱��������������ǽ���PALETTEENTRY���������
Ϊ�˷��������BOUNCEʹ��PALETTEENTRY�ṹ�����У��ýṹ�ǽ����߼���ɫ��ʱʹ�õ�LOGPALETTE�ṹ��һ���֡����Ŀǰλ�ã���0��32�������ھ�̬����iBall�С���TimerRoutine�ڼ䣬BOUNCE��PALETTEENTRY��Ա��Ϊ��ɫ��Ȼ����������һ��λ�ã�������Ԫ����Ϊ��ɫ��������ĺ������ı��ɫ�̣�
AnimatePalette (hPalette, 0, 33, plp->palPalEntry) ;
GDI�ı�33�߼���ɫ����Ŀ�еĵ�һ��������ʵ����ֻ�ı�����������ʹ����ϵͳ��ɫ�̱��еı仯���Ӧ��Ȼ���޸���ʾ���ϵ�Ӳ���ɫ�̱��������������ػ���Ϳ�ʼ�ƶ��ˡ�
BOUNCEִ��ʱ�����ᷢ��ͬʱִ��SYSPAL2��SYSPAL3Ч������á�
����AnimatePaletteִ�е÷dz��죬���ǵ�ֻ��һ������Ŀ�ı�ʱ������Ӧ�þ�������ı����е��߼���ɫ����Ŀ������BOUNCE���е㸴�ӣ���Ϊ��Ҫ���ص�����iBallҪ�����ӣ�Ȼ���ټ��١�һ�ַ�����ʹ�������������ֱ��ΪiBallOld���趨���Ŀǰλ�ã���iBallMin��iBall��iBallOld�н�С�ģ���Ȼ�����Ϳ�����������������AnimatePalette���ı�������Ŀ�ˣ�
iBallMin = min (iBall, iBallOld) ; AnimatePalette (hPal, iBallMin, 2, plp->palPalEntry + iBallMin) ;
������һ�ַ����������ȼٶ���������һ��PALETTEENTRY�ṹ��
PALETTEENTRY pe ;
��TimerRoutine�ڼ䣬����PALETTEENTRY��λ��Ϊ��ɫ��������AnimatePalette���ı��߼���ɫ����iBallλ�õ�һ����Ŀ��
pe.peRed = 255 ; pe.peGreen = 255 ; pe.peBlue = 255 ; pe.peFlags = PC_RESERVED ; AnimatePalette (hPalette, iBall, 1, &pe) ;
Ȼ�������ʾ��BOUNCE�е�iBall����ֵ����PALETTEENTRY�ṹ����λ����Ϊ��ɫ��Ȼ���ٴκ���AnimatePalette��
pe.peRed = 255 ; pe.peGreen = 0 ; pe.peBlue = 0 ; pe.peFlags = PC_RESERVED ; AnimatePalette (hPalette, iBall, 1, &pe) ;
�������������ǶԶ�����һ����ͳ�ļ�˵��������ʵ���ϲ����ʺϵ�ɫ�̶�������Ϊ�����Ȼ���������п���λ�á���ɫ�̶������ʺ����ʾ�˶����ظ�ͼ����
һ����Ŀ�ĵ�ɫ�̶���
��
��ɫ�̶�����һ������Ȥ�ķ�����ǣ�����ֻʹ��һ����ɫ����Ŀ�����һЩ��Ȥ�ļ����������ʽ16-8��ʾ��FADER��ʽ�������ʽҲ��Ҫǰ���PALANIM.C������
��ʽ16-8 FADER FADER.C /*-------------------------------------------------------------------------- FADER.C -- Palette Animation Demo (c) Charles Petzold, 1998 --------------------------------------------------------------------------*/ #include <windows.h> #define ID_TIMER 1 TCHAR szAppName [] = TEXT ("Fader") ; TCHAR szTitle [] = TEXT ("Fader: Palette Animation Demo") ; static LOGPALETTE lp ; HPALETTE CreateRoutine (HWND hwnd) { HPALETTE hPalette ; lp.palVersion = 0x0300 ; lp.palNumEntries = 1 ; lp.palPalEntry[0].peRed = 255 ; lp.palPalEntry[0].peGreen = 255 ; lp.palPalEntry[0].peBlue = 255 ; lp.palPalEntry[0].peFlags = PC_RESERVED ; hPalette = CreatePalette (&lp) ; SetTimer (hwnd, ID_TIMER, 50, NULL) ; return hPalette ; } void PaintRoutine (HDC hdc, int cxClient, int cyClient) { static TCHAR szText [] = TEXT (" Fade In and Out ") ; int x, y ; SIZE sizeText ; SetTextColor (hdc, PALETTEINDEX (0)) ; GetTextExtentPoint32 (hdc, szText, lstrlen (szText), &sizeText) ; for (x = 0 ; x < cxClient ; x += sizeText.cx) for (y = 0 ; y < cyClient ; y += sizeText.cy) { TextOut (hdc, x, y, szText, lstrlen (szText)) ; } return ; } void TimerRoutine (HDC hdc, HPALETTE hPalette) { static BOOL bFadeIn = TRUE ; if (bFadeIn) { lp.palPalEntry[0].peRed -= 4 ; lp.palPalEntry[0].peGreen -= 4 ; if ( lp.palPalEntry[0].peRed == 3) bFadeIn = FALSE ; } else { lp.palPalEntry[0].peRed += 4 ; lp.palPalEntry[0].peGreen += 4 ; if (lp.palPalEntry[0].peRed == 255) bFadeIn = TRUE ; } AnimatePalette (hPalette, 0, 1, lp.palPalEntry) ; return ; } void DestroyRoutine (HWND hwnd, HPALETTE hPalette) { KillTimer (hwnd, ID_TIMER) ; DeleteObject (hPalette) ; return ; }
FADER����ʾ��������ʾ���������ִ���Fade In And Out��������������ʾΪ��ɫ�����춰�ɫ�������Ӵ���˵�ǿ��������ġ�ͨ��ʹ�õ�ɫ�̶�����FADER�����ؽ����ֵ���ɫ��Ϊ��ɫ��Ȼ���ٸĻذ�ɫ������һ��һ����ظ������־��н��ֽ�������ʾЧ���ˡ�
FADER��CreateRoutine��ʽ�������߼���ɫ�̣���ֻ��Ҫһ����ɫ����Ŀ��������ɫ��ʼ��Ϊ��ɫ����ɫ����ɫ����ɫֵ����Ϊ255����PaintRoutine�У����������𣬵��߼���ɫ��ѡ��װ�����ݲ��������ᣬPALANIM���й��˺�ʽ����FADER����SetTextColor��������ɫ�趨ΪPALETTEINDEX(0)������ζ��������ɫ�趨Ϊ��ɫ�̱����еĵ�һ����Ŀ������Ŀ��ʼΪ��ɫ��Ȼ��FADER�á�Fade In And Out�������ִ������ʾ������ʱ���Ӵ������ǰ�ɫ������Ҳ�ǰ�ɫ���������ֲ��ɼ���
��TimerRoutine��ʽ�У�FADERͨ���ı�PALETTEENTRY�ṹ�����䴫�ݸ�AnimatePalette����ɵ�ɫ�̶������������ÿһ��WM_TIMERѶϢ����ʽ������ɫ����ɫֵ��4��ֱ�����3��Ȼ�Ὣ��Щֵ��4��ֱ�����255���⽫ʹ������ɫ�𽥴Ӱ�ɫ�䵽��ɫ��Ȼ���ֻص���ɫ��
��ʽ16-9��ʾ��ALLCOLOR��ʽֻ�����߼���ɫ�̵�һ����Ŀ����ʾ��ʾ��������ɫ��������ɫ����Ȼ����ʽ����ͬʱ��ʾ��Щ��ɫ������������ʾ�������ʾ����18λԪ�Ľ����ȣ���ʱ����262144�ֲ�ͬ����ɫ������ô��������ɫ���55������ٶ��£�ֻ��Ҫ4Сʱ�Ϳ�����өĻ�Ͽ������е���ɫ��
��ʽ16-9 ALLCOLOR ALLCOLOR.C /*--------------------------------------------------------------------------- ALLCOLOR.C -- Palette Animation Demo (c) Charles Petzold, 1998 -----------------------------------------------------------------------------*/ #include <windows.h> #define ID_TIMER 1 TCHAR szAppName [] = TEXT ("AllColor") ; TCHAR szTitle [] = TEXT ("AllColor: Palette Animation Demo") ; static int iIncr ; static PALETTEENTRY pe ; HPALETTE CreateRoutine (HWND hwnd) { HDC hdc ; HPALETTE hPalette ; LOGPALETTE lp ; // Determine the color resolution and set iIncr hdc = GetDC (hwnd) ; iIncr = 1 << (8 - GetDeviceCaps (hdc, COLORRES) / 3) ; ReleaseDC (hwnd, hdc) ; // Create the logical palette lp.palVersion = 0x0300 ; lp.palNumEntries = 1 ; lp.palPalEntry[0].peRed = 0 ; lp.palPalEntry[0].peGreen = 0 ; lp.palPalEntry[0].peBlue = 0 ; lp.palPalEntry[0].peFlags = PC_RESERVED ; hPalette = CreatePalette (&lp) ; // Save global for less typing pe = lp.palPalEntry[0] ; SetTimer (hwnd, ID_TIMER, 10, NULL) ; return hPalette ; } void DisplayRGB (HDC hdc, PALETTEENTRY * ppe) { TCHAR szBuffer [16] ; wsprintf (szBuffer, TEXT (" %02X-%02X-%02X "), ppe->peRed, ppe->peGreen, ppe->peBlue) ; TextOut (hdc, 0, 0, szBuffer, lstrlen (szBuffer)) ; } void PaintRoutine (HDC hdc, int cxClient, int cyClient) { HBRUSH hBrush ; RECT rect ; // Draw Palette Index 0 on entire window hBrush = CreateSolidBrush (PALETTEINDEX (0)) ; SetRect (&rect, 0, 0, cxClient, cyClient) ; FillRect (hdc, &rect, hBrush) ; DeleteObject (SelectObject (hdc, GetStockObject (WHITE_BRUSH))) ; // Display the RGB value DisplayRGB (hdc, &pe) ; return ; } void TimerRoutine (HDC hdc, HPALETTE hPalette) { static BOOL bRedUp = TRUE, bGreenUp = TRUE, bBlueUp = TRUE ; // Define new color value pe.peBlue += (bBlueUp ? iIncr : -iIncr) ; if ( pe.peBlue == (BYTE) (bBlueUp ? 0 : 256 - iIncr)) { pe.peBlue = (bBlueUp ? 256 - iIncr : 0) ; bBlueUp ^= TRUE ; pe.peGreen += (bGreenUp ? iIncr : -iIncr) ; if ( pe.peGreen == (BYTE) (bGreenUp ? 0 : 256 - iIncr)) { pe.peGreen = (bGreenUp ? 256 - iIncr : 0) ; bGreenUp ^= TRUE ; pe.peRed += (bRedUp ? iIncr : -iIncr) ; if ( pe.peRed == (BYTE) (bRedUp ? 0 : 256 - iIncr)) { pe.peRed = (bRedUp ? 256 - iIncr : 0) ; bRedUp ^= TRUE ; } } } // Animate the palette AnimatePalette (hPalette, 0, 1, &pe) ; DisplayRGB (hdc, &pe) ; return ; } void DestroyRoutine (HWND hwnd, HPALETTE hPalette) { KillTimer (hwnd, ID_TIMER) ; DeleteObject (hPalette) ; return ; }
�ڽṹ�ϣ�ALLCOLOR��FADER�dz����ơ���CreateRoutine�У�ALLCOLORֻ��һ����Ϊ��ɫ�ĵ�ɫ����Ŀ��PALETTEENTRY�ṹ��red��green��blue��λ��Ϊ0����������ɫ�̡���PaintRoutine�У�ALLCOLOR��PALETTEINDEX(0)����ʵ�Ļ�ˢ��������FillRect���ô˻�ˢΪ������ʾ������ɫ��
��TimerRoutine�У�ALLCOLORͨ���ı�PALETTEENTRY��ɫ������AnimatePalette��������ɫ�̡��ұ�дALLCOLOR��ʽ���Ա���ɫ�仯˳�������ȣ���ɫֵ�������ӡ��ﵽ���ʱ����ɫֵ���ӣ�����ɫֵ�������١���ɫ����ɫ����ɫֵ�����Ӻͼ���ȡ���iIncr��������CreateRoutine�ڼ䣬�⽫������COLORRES������GetDeviceCaps���ص�ֵ�����㡣���磬���GetDeviceCaps����18����ôiIncr��Ϊ4�����������ɫ����Ҫ����Сֵ��
ALLCOLOR������ʾ��������Ͻ���ʾĿǰ��RGB��ɫֵ����������������ʽ���dz�춲���Ŀ�ģ���������֤���������õģ������ұ���������
����Ӧ�ó�ʽ
��
�ڹ���Ӧ�ó�ʽ�У����������ʾ��е�������ù��̺����á��ڵ���өĻ����ʾ��ȼ������Ȼ�򵥣����Ƕ�������ʹ����ø����������Ҹ��������ʾ�乤������
ʹ�õ�ɫ�̶�����һ���÷���������ʾ����ͨ�����ӵĹ��̡�����һ�����ӣ�ͼ�񲻱�ʮ�־�ȷ��ʵ���ϣ����ͼ��ܾ�ȷ������͸���Ĺ��ӣ��������˵�������������������˶��ġ���ʱ�÷��Ż����һЩ����ʽ16-10��ʾ��PIPES��ʽ�Ǵ˼����ļ�ʾ��������ʾ����������ˮƽ�Ĺ��ӣ�����������Ĺ��������������������������Ĺ�������������ƶ���
��ʽ16-10 PIPES
PIPES.C /*------------------------------------------------------------------------- PIPES.C -- Palette Animation Demo (c) Charles Petzold, 1998 ---------------------------------------------------------------------------*/ #include <windows.h> #define ID_TIMER 1 TCHAR szAppName [] = TEXT ("Pipes") ; TCHAR szTitle [] = TEXT ("Pipes: Palette Animation Demo") ; static LOGPALETTE * plp ; HPALETTE CreateRoutine (HWND hwnd) { HPALETTE hPalette ; int i ; plp = malloc (sizeof (LOGPALETTE) + 32 * sizeof (PALETTEENTRY)) ; // Initialize the fields of the LOGPALETTE structure plp->palVersion = 0x300 ; plp->palNumEntries = 16 ; for (i = 0 ; i <= 8 ; i++) { plp->palPalEntry[i].peRed = (BYTE) min (255, 0x20 * i) ; plp->palPalEntry[i].peGreen = 0 ; plp->palPalEntry[i].peBlue = (BYTE) min (255, 0x20 * i) ; plp->palPalEntry[i].peFlags = PC_RESERVED ; plp->palPalEntry[16 - i] = plp->palPalEntry[i] ; plp->palPalEntry[16 + i] = plp->palPalEntry[i] ; plp->palPalEntry[32 - i] = plp->palPalEntry[i] ; } hPalette = CreatePalette (plp) ; SetTimer (hwnd, ID_TIMER, 100, NULL) ; return hPalette ; } void PaintRoutine (HDC hdc, int cxClient, int cyClient) { HBRUSH hBrush ; int i ; RECT rect ; // Draw window background SetRect (&rect, 0, 0, cxClient, cyClient) ; hBrush = SelectObject (hdc, GetStockObject (WHITE_BRUSH)) ; FillRect (hdc, &rect, hBrush) ; // Draw the interiors of the pipes for (i = 0 ; i < 128 ; i++) { hBrush = CreateSolidBrush (PALETTEINDEX (i % 16)) ; SelectObject (hdc, hBrush) ; rect.left = (127 - i) * cxClient / 128 ; zrect.right = (128 - i) * cxClient / 128 ; rect.top = 4 * cyClient / 14 ; rect.bottom = 5 * cyClient / 14 ; FillRect (hdc, &rect, hBrush) ; rect.left = i * cxClient / 128 ; rect.right = ( i + 1) * cxClient / 128 ; rect.top = 9 * cyClient / 14 ; rect.bottom = 10 * cyClient / 14 ; FillRect (hdc, &rect, hBrush) ; DeleteObject (SelectObject (hdc, GetStockObject (WHITE_BRUSH))) ; } // Draw the edges of the pipes MoveToEx (hdc, 0, 4 * cyClient / 14, NULL) ; LineTo (hdc, cxClient, 4 * cyClient / 14) ; MoveToEx (hdc, 0, 5 * cyClient / 14, NULL) ; LineTo (hdc, cxClient, 5 * cyClient / 14) ; MoveToEx (hdc, 0, 9 * cyClient / 14, NULL) ; LineTo (hdc, cxClient, 9 * cyClient / 14) ; MoveToEx (hdc, 0, 10 * cyClient / 14, NULL) ; LineTo (hdc, cxClient, 10 * cyClient / 14) ; return ; } void TimerRoutine (HDC hdc, HPALETTE hPalette) { static int iIndex ; AnimatePalette (hPalette, 0, 16, plp->palPalEntry + iIndex) ; iIndex = (iIndex + 1) % 16 ; return ; } void DestroyRoutine (HWND hwnd, HPALETTE hPalette) { KillTimer (hwnd, ID_TIMER) ; DeleteObject (hPalette) ; free (plp) ; return ; }
PIPESΪ����ʹ����16����ɫ����Ŀ���������ܻ�ʹ�ø��ٵ���Ŀ����С��ʱ��������Ҫ�������㹻����Ŀ����ʾ�����ķ�����������ɫ����ĿҪ����һ����̬��ͷ�á�
��ʽ16-11��ʾ��TUNNEL��ʽ�������ʽ����̰�ĵij�ʽ����Ϊ����ʹ����128����ɫ����Ŀ�����Ǵ�Ч��������ֵ����������
��ʽ16-11 TUNNEL TUNNEL.C /*--------------------------------------------------------------------------- TUNNEL.C -- Palette Animation Demo (c) Charles Petzold, 1998 ----------------------------------------------------------------------------*/ #include <windows.h> #define ID_TIMER 1 TCHAR szAppName [] = TEXT ("Tunnel") ; TCHAR szTitle [] = TEXT ("Tunnel: Palette Animation Demo") ; static LOGPALETTE * plp ; HPALETTE CreateRoutine (HWND hwnd) { BYTE byGrayLevel ; HPALETTE hPalette ; int i ; plp = malloc (sizeof (LOGPALETTE) + 255 * sizeof (PALETTEENTRY)) ; // Initialize the fields of the LOGPALETTE structure plp->palVersion = 0x0300 ; plp->palNumEntries = 128 ; for (i = 0 ; i < 128 ; i++) { if (i < 64) byGrayLevel = (BYTE) (4 * i) ; else byGrayLevel = (BYTE) min (255, 4 * (128 - i)) ; plp->palPalEntry[i].peRed = byGrayLevel ; plp->palPalEntry[i].peGreen = byGrayLevel ; plp->palPalEntry[i].peBlue = byGrayLevel ; plp->palPalEntry[i].peFlags = PC_RESERVED ; plp->palPalEntry[i + 128].peRed = byGrayLevel ; plp->palPalEntry[i + 128].peGreen = byGrayLevel ; plp->palPalEntry[i + 128].peBlue = byGrayLevel ; plp->palPalEntry[i + 128].peFlags = PC_RESERVED ; } hPalette = CreatePalette (plp) ; SetTimer (hwnd, ID_TIMER, 50, NULL) ; return hPalette ; } void PaintRoutine (HDC hdc, int cxClient, int cyClient) { HBRUSH hBrush ; int i ; RECT rect ; for (i = 0 ; i < 127 ; i++) { // Use a RECT structure for each of 128 rectangles rect.left = i * cxClient / 255 ; rect.top = i * cyClient / 255 ; rect.right = cxClient - i * cxClient / 255 ; rect.bottom = cyClient - i * cyClient / 255 ; hBrush = CreateSolidBrush (PALETTEINDEX (i)) ; // Fill the rectangle and delete the brush FillRect (hdc, &rect, hBrush) ; DeleteObject (hBrush) ; } return ; } void TimerRoutine (HDC hdc, HPALETTE hPalette) { static int iLevel ; iLevel = (iLevel + 1) % 128 ; AnimatePalette (hPalette, 0, 128, plp->palPalEntry + iLevel) ; return ; } void DestroyRoutine (HWND hwnd, HPALETTE hPalette) { KillTimer (hwnd, ID_TIMER) ; DeleteObject (hPalette) ; free (plp) ; return ; }
TUNNEL��128����ɫ����Ŀ��ʹ��64���ƶ��Ļҽף��Ӻڵ��ף��ٴӰ׵��ڣ��������������е�Ч����
��ɫ�̺���ʵ����ͼ��
��
��Ȼ�����������Ѿ������������Ȥ���£�������ʾɫ�ʵ����ס����˵�ɫ�̶���������ɫ�̹�����������Ŀ����������8λԪ��ʾģʽ����ʾ��ʵ�����е�ͼ�񡣶�춱��µ����ಿ�֣����������о�һ�¡��������������ģ���ʹ��packed DIB��GDI����ͼ�����DIB����ʱ�����밴�ղ�ͬ�ķ�����ʹ�õ�ɫ�̡������������ʽ�������õ�ɫ������������ͼ�ĸ��ּ�����
��ɫ�̺�packed DIB
��
����������ʽ����������ǽ�������packed DIB��������һϵ�к�ʽ����Щ��ʽ���ڳ�ʽ16-12��ʾ��PACKEDIB�����С�
��ʽ16-12 PACKEDIB���� PACKEDIB.H /*------------------------------------------------------------------------- PACKEDIB.H -- Header file for PACKEDIB.C (c) Charles Petzold, 1998 --------------------------------------------------------------------------*/ #include <windows.h> BITMAPINFO * PackedDibLoad (PTSTR szFileName) ; int PackedDibGetWidth (BITMAPINFO * pPackedDib) ; int PackedDibGetHeight (BITMAPINFO * pPackedDib) ; int PackedDibGetBitCount (BITMAPINFO * pPackedDib) ; int PackedDibGetRowLength (BITMAPINFO * pPackedDib) ; int PackedDibGetInfoHeaderSize (BITMAPINFO * pPackedDib) ; int PackedDibGetColorsUsed (BITMAPINFO * pPackedDib) ; int PackedDibGetNumColors (BITMAPINFO * pPackedDib) ; int PackedDibGetColorTableSize (BITMAPINFO * pPackedDib) ; RGBQUAD * PackedDibGetColorTablePtr (BITMAPINFO * pPackedDib) ; RGBQUAD * PackedDibGetColorTableEntry (BITMAPINFO * pPackedDib, int i) ; BYTE * PackedDibGetBitsPtr (BITMAPINFO * pPackedDib) ; int PackedDibGetBitsSize (BITMAPINFO * pPackedDib) ; HPALETTE PackedDibCreatePalette (BITMAPINFO * pPackedDib) ;
PACKEDIB.C /*------------------------------------------------------------------------- PACKEDIB.C -- Routines for using packed DIBs (c) Charles Petzold, 1998 ---------------------------------------------------------------------------*/ #include <windows.h> /*--------------------------------------------------------------------------- PackedDibLoad: Load DIB File as Packed-Dib Memory Block ----------------------------------------------------------------------------*/ BITMAPINFO * PackedDibLoad (PTSTR szFileName) { BITMAPFILEHEADER bmfh ; BITMAPINFO * pbmi ; BOOL bSuccess ; DWORD dwPackedDibSize, dwBytesRead ; HANDLE hFile ; // Open the file: read access, prohibit write access hFile = CreateFile (szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL) ; if (hFile == INVALID_HANDLE_VALUE) return NULL ; // Read in the BITMAPFILEHEADER bSuccess = ReadFile ( hFile, &bmfh, sizeof (BITMAPFILEHEADER), &dwBytesRead, NULL) ; if (!bSuccess || (dwBytesRead != sizeof (BITMAPFILEHEADER)) || (bmfh.bfType != * (WORD *) "BM")) { CloseHandle (hFile) ; return NULL ; } // Allocate memory for the packed DIB & read it in dwPackedDibSize = bmfh.bfSize - sizeof (BITMAPFILEHEADER) ; pbmi = malloc (dwPackedDibSize) ; bSuccess = ReadFile (hFile, pbmi, dwPackedDibSize, &dwBytesRead, NULL) ; CloseHandle (hFile) ; if (!bSuccess || (dwBytesRead != dwPackedDibSize)) { free (pbmi) ; return NULL ; } return pbmi ; } /*-------------------------------------------------------------------------- Functions to get information from packed DIB ----------------------------------------------------------------------------*/ int PackedDibGetWidth (BITMAPINFO * pPackedDib) { if (pPackedDib->bmiHeader.biSize == sizeof (BITMAPCOREHEADER)) return ((PBITMAPCOREINFO)pPackedDib)->bmciHeader.bcWidth ; else return pPackedDib->bmiHeader.biWidth ; } int PackedDibGetHeight (BITMAPINFO * pPackedDib) { if (pPackedDib->bmiHeader.biSize == sizeof (BITMAPCOREHEADER)) return ((PBITMAPCOREINFO)pPackedDib)->bmciHeader.bcHeight ; else return abs (pPackedDib->bmiHeader.biHeight) ; } int PackedDibGetBitCount (BITMAPINFO * pPackedDib) { if (pPackedDib->bmiHeader.biSize == sizeof (BITMAPCOREHEADER)) return ((PBITMAPCOREINFO)pPackedDib)->bmciHeader.bcBitCount ; else return pPackedDib->bmiHeader.biBitCount ; } int PackedDibGetRowLength (BITMAPINFO * pPackedDib) { return (( PackedDibGetWidth (pPackedDib) * PackedDibGetBitCount (pPackedDib) + 31) & ~31) >> 3 ; } /*--------------------------------------------------------------------------- PackedDibGetInfoHeaderSize includes possible color masks! ----------------------------------------------------------------------------*/ int PackedDibGetInfoHeaderSize (BITMAPINFO * pPackedDib) { if ( pPackedDib->bmiHeader.biSize == sizeof (BITMAPCOREHEADER)) return ((PBITMAPCOREINFO)pPackedDib)->bmciHeader.bcSize ; else if (pPackedDib->bmiHeader.biSize == sizeof (BITMAPINFOHEADER)) return pPackedDib->bmiHeader.biSize + (pPackedDib->bmiHeader.biCompression == BI_BITFIELDS ? 12 : 0) ; else return pPackedDib->bmiHeader.biSize ; } /*-------------------------------------------------------------------------- PackedDibGetColorsUsed returns value in information header; could be 0 to indicate non-truncated color table! ----------------------------------------------------------------------------*/ int PackedDibGetColorsUsed (BITMAPINFO * pPackedDib) { if (pPackedDib->bmiHeader.biSize == sizeof (BITMAPCOREHEADER)) return 0 ; else return pPackedDib->bmiHeader.biClrUsed ; } /*---------------------------------------------------------------------------- PackedDibGetNumColors is actual number of entries in color table -----------------------------------------------------------------------------*/ int PackedDibGetNumColors (BITMAPINFO * pPackedDib) { int iNumColors ; iNumColors = PackedDibGetColorsUsed (pPackedDib) ; if ( iNumColors == 0 && PackedDibGetBitCount (pPackedDib) < 16) iNumColors =1 << PackedDibGetBitCount (pPackedDib) ; return iNumColors ; } int PackedDibGetColorTableSize (BITMAPINFO * pPackedDib) { if (pPackedDib->bmiHeader.biSize == sizeof (BITMAPCOREHEADER)) return PackedDibGetNumColors (pPackedDib) * sizeof (RGBTRIPLE) ; else return PackedDibGetNumColors (pPackedDib) * sizeof (RGBQUAD) ; } RGBQUAD * PackedDibGetColorTablePtr (BITMAPINFO * pPackedDib) { if (PackedDibGetNumColors (pPackedDib) == 0) return 0 ; return (RGBQUAD *) (((BYTE *) pPackedDib) + PackedDibGetInfoHeaderSize (pPackedDib)) ; } RGBQUAD * PackedDibGetColorTableEntry (BITMAPINFO * pPackedDib, int i) { if ( PackedDibGetNumColors (pPackedDib) == 0) return 0 ; if ( pPackedDib->bmiHeader.biSize == sizeof (BITMAPCOREHEADER)) return (RGBQUAD *) (((RGBTRIPLE *) PackedDibGetColorTablePtr (pPackedDib)) + i) ; else return PackedDibGetColorTablePtr (pPackedDib) + i ; } /*-------------------------------------------------------------------------- PackedDibGetBitsPtr finally! ----------------------------------------------------------------------------*/ BYTE * PackedDibGetBitsPtr (BITMAPINFO * pPackedDib) { return ((BYTE *) pPackedDib)+ PackedDibGetInfoHeaderSize (pPackedDib) + PackedDibGetColorTableSize (pPackedDib) ; } /*----------------------------------------------------------------------------- PackedDibGetBitsSize can be calculated from the height and row length if it's not explicitly in the biSizeImage field -----------------------------------------------------------------------------*/ int PackedDibGetBitsSize (BITMAPINFO * pPackedDib) { if ((pPackedDib->bmiHeader.biSize != sizeof (BITMAPCOREHEADER)) && (pPackedDib->bmiHeader.biSizeImage != 0)) return pPackedDib->bmiHeader.biSizeImage ; return PackedDibGetHeight (pPackedDib) * PackedDibGetRowLength (pPackedDib) ; } /*--------------------------------------------------------------------------- PackedDibCreatePalette creates logical palette from PackedDib -----------------------------------------------------------------------------*/ HPALETTE PackedDibCreatePalette (BITMAPINFO * pPackedDib) { HPALETTE hPalette ; int i, iNumColors ; LOGPALETTE * plp ; RGBQUAD * prgb ; if (0 == ( iNumColors = PackedDibGetNumColors (pPackedDib))) return NULL ; plp = malloc (sizeof (LOGPALETTE) * (iNumColors - 1) * sizeof (PALETTEENTRY)) ; plp->palVersion = 0x0300 ; plp->palNumEntries = iNumColors ; for (i = 0 ; i < iNumColors ; i++) { prgb = PackedDibGetColorTableEntry (pPackedDib, i) ; plp->palPalEntry[i].peRed = prgb->rgbRed ; plp->palPalEntry[i].peGreen = prgb->rgbGreen ; plp->palPalEntry[i].peBlue = prgb->rgbBlue ; plp->palPalEntry[i].peFlags = 0 ; } hPalette = CreatePalette (plp) ; free (plp) ; return hPalette ; }
��һ����ʽ��PackedDibLoad������Ψһ�IJ�����Ϊ��������������ָ���������packed DIB��ָ�ꡣ�������к�ʽ�������packed DIBָ����Ϊ���ǵĵ�һ�������������й�DIB����Ѷ����Щ��ʽ�������¶��ϡ�˳�����е������С�ÿ����ʽ��ʹ�ô�ǰ�溯ʽ��õ���Ѷ��
�Ҳ������˵�����ڴ���packed DIBʱ���õġ���������ʽ�������ң���Ҳ������һ����������չ������Ϊ�Ҳ���Ϊ���Ǵ���packed DIB��һ���÷�������д��������ĺ�ʽʱ����������Եط�����һ�㣺
dwPixel = PackedDibGetPixel (pPackedDib, x, y) ;
���ֺ�ʽ����̫��ij�״��ʽ���У������Ч�ʷdz��Ͷ��Һ��������µ����潫����һ������Ϊ���õķ�����
���⣬����ע�⵽���������ຯʽ����Ҫ��OS/2���ݵ�DIB��ȡ��ͬ�Ĵ���������������ʽ��Ƶ���ؼ��BITMAPINFO�ṹ�ĵ�һ����λ�Ƿ���BITMAPCOREHEADER�ṹ�Ĵ�С��ͬ��
�ر�ע������һ����ʽPackedDibCreatePalette�������ʽ��DIB�е���ɫ����������ɫ�̡����DIB��û����ɫ��������ζ��DIB��ÿͼ����16��24��32λԪ������ô�Ͳ�������ɫ�̡�������ʱ�Ὣ��DIB��ɫ�������ĵ�ɫ�̳�ΪDIB �Լ��� ��ɫ�̡�
PACKEDIB����������SHOWDIB3�����ʽ16-13��ʾ��
��ʽ16-13 SHOWDIB3 SHOWDIB3.C /*-------------------------------------------------------------------------- SHOWDIB3.C -- Displays DIB with native palette (c) Charles Petzold, 1998 ----------------------------------------------------------------------------*/ #include <windows.h> #include "PackeDib.h" #include "resource.h" LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; TCHAR szAppName[] = TEXT ("ShowDib3") ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = szAppName ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox ( NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow ( szAppName, TEXT ("Show DIB #3: Native Palette"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) { static BITMAPINFO * pPackedDib ; static HPALETTE hPalette ; static int cxClient, cyClient ; 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") ; HDC hdc ; PAINTSTRUCT ps ; switch (message) { case WM_CREATE: ofn.lStructSize = sizeof (OPENFILENAME) ; ofn.hwndOwner = hwnd ; ofn.hInstance = NULL ; ofn.lpstrFilter = szFilter ; ofn.lpstrCustomFilter = NULL ; ofn.nMaxCustFilter = 0 ; ofn.nFilterIndex = 0 ; ofn.lpstrFile = szFileName ; ofn.nMaxFile = MAX_PATH ; ofn.lpstrFileTitle = szTitleName ; ofn.nMaxFileTitle = MAX_PATH ; ofn.lpstrInitialDir = NULL ; ofn.lpstrTitle = NULL ; ofn.Flags = 0 ; ofn.nFileOffset = 0 ; ofn.nFileExtension = 0 ; ofn.lpstrDefExt = TEXT ("bmp") ; ofn.lCustData = 0 ; ofn.lpfnHook = NULL ; ofn.lpTemplateName = NULL ; return 0 ; case WM_SIZE: cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; return 0 ; case WM_COMMAND: switch (LOWORD (wParam)) { case IDM_FILE_OPEN: // Show the File Open dialog box if (!GetOpenFileName (&ofn)) return 0 ; // If there's an existing packed DIB, free the memory if (pPackedDib) { free (pPackedDib) ; pPackedDib = NULL ; } // If there's an existing logical palette, delete it if (hPalette) { DeleteObject (hPalette) ; hPalette = NULL ; } // Load the packed DIB into memory SetCursor (LoadCursor (NULL, IDC_WAIT)) ; ShowCursor (TRUE) ; pPackedDib = PackedDibLoad (szFileName) ; ShowCursor (FALSE) ; SetCursor (LoadCursor (NULL, IDC_ARROW)) ; if (pPackedDib) { // Create the palette from the DIB color table hPalette = PackedDibCreatePalette (pPackedDib) ; } else { MessageBox ( hwnd, TEXT ("Cannot load DIB file"), szAppName, 0) ; } InvalidateRect (hwnd, NULL, TRUE) ; return 0 ; } break ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; if (hPalette) { SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; } if (pPackedDib) SetDIBitsToDevice (hdc, 0,0,PackedDibGetWidth (pPackedDib), PackedDibGetHeight (pPackedDib), 0,0,0,PackedDibGetHeight (pPackedDib), PackedDibGetBitsPtr (pPackedDib), pPackedDib, DIB_RGB_COLORS) ; EndPaint (hwnd, &ps) ; return 0 ; 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) break ; hdc = GetDC (hwnd) ; SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; UpdateColors (hdc) ; ReleaseDC (hwnd, hdc) ; break ; case WM_DESTROY: if (pPackedDib) free (pPackedDib) ; if (hPalette) DeleteObject (hPalette) ; PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
SHOWDIB3.RC ��ժ¼�� //Microsoft Developer Studio generated resource script. #include "resource.h" #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// // Menu SHOWDIB3 MENU DISCARDABLE BEGIN POPUP "&File" BEGIN MENUITEM "&Open", IDM_FILE_OPEN END END
RESOURCE.H ��ժ¼�� // Microsoft Developer Studio generated include file. // Used by ShowDib3.rc #define IDM_FILE_OPEN 40001
SHOWDIB3�е��Ӵ�ѶϢ������ʽ��packed DIBָ����Ϊ��̬������ά�����Ӵ�ѶϢ������ʽ�ڡ�File Open�������ڼ����PACKEDIB.C�е�PackedDibLoad��ʽʱ����˴�ָ�ꡣ�ڴ���������Ĺ����У�SHOWDIB3Ҳ����PackedDibCreatePalette����ÿ������DIB�ĵ�ɫ�̡�ע�⣬����SHOWDIB3ʲôʱ��׼�������µ�DIB����Ӧ���ͷ�ǰһ��DIB�ļ����壬��ɾ��ǰһ��DIB�ĵ�ɫ�̡��ڴ���WM_DESTROYѶϢ�ij����У������DIB�����ͷţ�����ĵ�ɫ������ɾ����
����WM_PAINTѶϢ�ܼ򵥣�������ڵ�ɫ�̣���SHOWDIB3����ѡ��װ�����ݲ���������Ȼ��������SetDIBitsToDevice���������й�DIB�ĺ�ʽ��Ѷ����������ߺ�ָ��DIBͼ��λԪ��ָ�� )����Щ��Ѷ��PACKEDIB�еĺ�ʽ��á�
���⣬���סSHOWDIB3����DIB�е���ɫ�������˵�ɫ�̡������DIB��û����ɫ����ͨ����16λԪ��24λԪ��32λԪDIB��������Ͳ�������ɫ�̡���8λԪ��ʾģʽ����ʾDIBʱ����ֻ���ñ�׼������20����ɫ��ʾ��
��������������ֽ����������һ���Ǽ򵥵�ʹ�á�ͨ�á���ɫ�̣����ֵ�ɫ�����������ͼ�Ρ���Ҳ�����Լ�������ɫ�̡��ڶ��ֽ�������Ƿ���DIB��ͼ��λԪ��������Ҫ��ʾͼ��������ɫ�������ԣ��ڶ��ַ������漰����Ĺ�������춳�ʽд���ߺʹ�����������ˣ��������ҽ��ڱ��½���֮ǰ���������ʹ�õڶ��ַ�����
��ͨ�á���ɫ��
��
��ʽ16-14��ʾ��SHOWDIB4��ʽ������һ��ͨ�õĵ�ɫ�̣��������ʾ���뵽��ʽ�е�����DIB�����⣬SHOWDIB4��SHOWDIB3�dz����ơ�
��ʽ16-14 SHOWDIB4 SHOWDIB4.C /*--------------------------------------------------------------------------- SHOWDIB4.C -- Displays DIB with "all-purpose" palette (c) Charles Petzold, 1998 -----------------------------------------------------------------------------*/ #include <windows.h> #include "..\\ShowDib3\\PackeDib.h" #include "resource.h" LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; TCHAR szAppName[] = TEXT ("ShowDib4") ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = szAppName ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox ( NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow ( szAppName, TEXT ("Show DIB #4: All-Purpose Palette"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } /*----------------------------------------------------------------------------- CreateAllPurposePalette: Creates a palette suitable for a wide variety of images; the palette has 247 entries, but 15 of them are duplicates or match the standard 20 colors. -----------------------------------------------------------------------------*/ HPALETTE CreateAllPurposePalette (void) { HPALETTE hPalette ; int i, incr, R, G, B ; LOGPALETTE * plp ; plp = malloc (sizeof (LOGPALETTE) + 246 * sizeof (PALETTEENTRY)) ; plp->palVersion = 0x0300 ; plp->palNumEntries = 247 ; // The following loop calculates 31 gray shades, but 3 of them // will match the standard 20 colors for (i = 0, G = 0, incr = 8 ; G <= 0xFF ; i++, G += incr) { plp->palPalEntry[i].peRed = (BYTE) G ; plp->palPalEntry[i].peGreen = (BYTE) G ; plp->palPalEntry[i].peBlue = (BYTE) G ; plp->palPalEntry[i].peFlags = 0 ; incr = (incr == 9 ? 8 : 9) ; } // The following loop is responsible for 216 entries, but 8 of // them will match the standard 20 colors, and another // 4 of them will match the gray shades above. for (R = 0 ; R <= 0xFF ; R += 0x33) for (G = 0 ; G <= 0xFF ; G += 0x33) for (B = 0 ; B <= 0xFF ; B += 0x33) { plp->palPalEntry [i].peRed = (BYTE) R ; plp->palPalEntry [i].peGreen = (BYTE) G ; plp->palPalEntry [i].peBlue = (BYTE) B ; plp->palPalEntry [i].peFlags = 0 ; i++ ; } hPalette = CreatePalette (plp) ; free (plp) ; return hPalette ; } LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) { static BITMAPINFO * pPackedDib ; static HPALETTE hPalette ; static int cxClient, cyClient ; 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") ; HDC hdc ; PAINTSTRUCT ps ; switch (message) { case WM_CREATE: ofn.lStructSize = sizeof (OPENFILENAME) ; ofn.hwndOwner = hwnd ; ofn.hInstance = NULL ; ofn.lpstrFilter = szFilter ; ofn.lpstrCustomFilter = NULL ; ofn.nMaxCustFilter = 0 ; ofn.nFilterIndex = 0 ; ofn.lpstrFile = szFileName ; ofn.nMaxFile = MAX_PATH ; ofn.lpstrFileTitle = szTitleName ; ofn.nMaxFileTitle = MAX_PATH ; ofn.lpstrInitialDir = NULL ; ofn.lpstrTitle = NULL ; ofn.Flags = 0 ; ofn.nFileOffset = 0 ; ofn.nFileExtension = 0 ; ofn.lpstrDefExt = TEXT ("bmp") ; ofn.lCustData = 0 ; ofn.lpfnHook = NULL ; ofn.lpTemplateName = NULL ; // Create the All-Purpose Palette hPalette = CreateAllPurposePalette () ; return 0 ; case WM_SIZE: cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; return 0 ; case WM_COMMAND: switch (LOWORD (wParam)) { case IDM_FILE_OPEN: // Show the File Open dialog box if (!GetOpenFileName (&ofn)) return 0 ; // If there's an existing packed DIB, free the memory if (pPackedDib) { free (pPackedDib) ; pPackedDib = NULL ; } // Load the packed DIB into memory SetCursor (LoadCursor (NULL, IDC_WAIT)) ; ShowCursor (TRUE) ; pPackedDib = PackedDibLoad (szFileName) ; ShowCursor (FALSE) ; SetCursor (LoadCursor (NULL, IDC_ARROW)) ; if (!pPackedDib) { MessageBox ( hwnd, TEXT ("Cannot load DIB file"), szAppName, 0) ; } InvalidateRect (hwnd, NULL, TRUE) ; return 0 ; } break ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; if (pPackedDib) { SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; SetDIBitsToDevice (hdc,0,0,PackedDibGetWidth (pPackedDib), PackedDibGetHeight (pPackedDib), 0,0,0,PackedDibGetHeight (pPackedDib), PackedDibGetBitsPtr (pPackedDib), pPackedDib, DIB_RGB_COLORS) ; } EndPaint (hwnd, &ps) ; return 0 ; case WM_QUERYNEWPALETTE: hdc = GetDC (hwnd) ; SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; InvalidateRect (hwnd, NULL, TRUE) ; ReleaseDC (hwnd, hdc) ; return TRUE ; case WM_PALETTECHANGED: if ((HWND) wParam != hwnd) hdc = GetDC (hwnd) ; SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; UpdateColors (hdc) ; ReleaseDC (hwnd, hdc) ; break ; case WM_DESTROY: if (pPackedDib) free (pPackedDib) ; DeleteObject (hPalette) ; PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
SHOWDIB4.RC ��ժ¼�� //Microsoft Developer Studio generated resource script. #include "resource.h" #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// // Menu SHOWDIB4 MENU DISCARDABLE BEGIN POPUP "&Open" BEGIN MENUITEM "&File", IDM_FILE_OPEN END END
RESOURCE.H ��ժ¼�� // Microsoft Developer Studio generated include file. // Used by ShowDib4.rc #define IDM_FILE_OPEN 40001
�ڴ���WM_CREATEѶϢʱ��SHOWDIB4������CreateAllPurposePalette�����ڳ�ʽ�б����õ�ɫ�̣�����WM_DESTROYѶϢ�����ڼ�ɾ��������Ϊ��ʽ֪����ɫ��һ�����ڣ������ڴ���WM_PAINT��WM_QUERYNEWPALETTE��WM_PALETTECHANGEDѶϢʱ�����ؼ���ɫ�̵Ĵ��ڡ�
CreateAllPurposePalette��ʽ�ƺ�����247����Ŀ�������߼���ɫ�̣���������ϵͳ��ɫ����������ʽ������ȡ��236����Ŀ����ȷ��ˣ������������ܷ��㡣��Щ��Ŀ����15�������ƻ���ӳ�䵽20�ֱ�׼�ı�����ɫ�С�
CreateAllPurposePalette�ӽ���31�ֻҽ׿�ʼ����0x00��0x09��0x11��0x1A��0x22��0x2B��0x33��0x3C��0x44��0x4D��0x55��0x5E��0x66��0x6F��0x77��0x80��0x88��0x91��0x99��0xA2��0xAA��0xB3��0xBB��0xC4��0xCC��0xD5��0xDD��0xE6��0xEE��0xF9��0xFF�ĺ�ɫ����ɫ����ɫֵ��ע�⣬��һ��������һ�����м����Ŀ���ڱ�׼��20�ֱ�����ɫ�С���һ����ʽ�ú�ɫ����ɫ����ɫֵ��������Ͻ�������ɫ0x00��0x33��0x66��0x99��0xCC��0xFF�������͹���216����ɫ����������8����ɫ�����˱�׼��20�ֱ�����ɫ��������4��������ǰ�����Ļҽס������PALETTEENTRY�ṹ��peFlags��λ��Ϊ0����Windows�����Ѹ��Ƶ���Ŀ�Ž�ϵͳ��ɫ�̡�
��Ȼ�أ�ʵ�ʵij�ʽ��ϣ������16λԪ��24λԪ����32λԪDIB����ѵ�ɫ�̣���ʽ������ʹ��DIB��ɫ������ʾ8λԪDIB��SHOWDIB4��������������ֻ��ÿ���¶�ʹ��ͨ�õ�ɫ�̡���ΪSHOWDIB4��һ��չʾ��ʽ��������������SHOWDIB3��ʾ��8λԪDIB���бȽϡ������һЩ����IJ�ɫDIB����ô�����ܻ�ó������Ľ��ۣ�SHOWDIB4û���㹻����ɫ����ȷ�ر�ʾ���޵�ɫ����
�����SHOWDIB4�е�CreateAllPurposePalette��ʽ�����飨������ͨ�����߼���ɫ�̵Ĵ�С���ٵ�ֻ�м�����Ŀ�ķ��������������ֵ���ɫ��ѡ��װ������ʱ��Windows��ֻʹ�õ�ɫ���е���ɫ������ʹ�ñ�׼��20����ɫ��ɫ�̵���ɫ��
�м�ɫ��ɫ��
��
Windows API����һ��ͨ�õ�ɫ�̣���ʽ����ͨ������CreateHalftonePalette����øõ�ɫ�̡�ʹ�ô˵�ɫ�̵ķ�����ʹ�ô�SHOWDIB4�е�CreateAllPurposePalette��õ�ɫ�̵ķ�����ͬ��������Ҳ���������ͼ����ģʽ�е�HALFTONE�趨����SetStretchBltMode�趨��һ��ʹ�á���ʽ16-15��ʾ��SHOWDIB5��ʽչʾ��ʹ���м�ɫ��ɫ�̵ķ�����
��ʽ16-15 SHOWDIB5 SHOWDIB5.C /*-------------------------------------------------------------------------- SHOWDIB5.C -- Displays DIB with halftone palette (c) Charles Petzold, 1998 --------------------------------------------------------------------------*/ #include <windows.h> #include "..\\ShowDib3\\PackeDib.h" #include "resource.h" LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; TCHAR szAppName[] = TEXT ("ShowDib5") ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = szAppName ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox ( NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow ( szAppName, TEXT ("Show DIB #5: Halftone Palette"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) { static BITMAPINFO * pPackedDib ; static HPALETTE hPalette ; static int cxClient, cyClient ; 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") ; HDC hdc ; PAINTSTRUCT ps ; switch (message) { case WM_CREATE: ofn.lStructSize = sizeof (OPENFILENAME) ; ofn.hwndOwner = hwnd ; ofn.hInstance = NULL ; ofn.lpstrFilter = szFilter ; ofn.lpstrCustomFilter = NULL ; ofn.nMaxCustFilter = 0 ; ofn.nFilterIndex = 0 ; ofn.lpstrFile = szFileName ; ofn.nMaxFile = MAX_PATH ; ofn.lpstrFileTitle = szTitleName ; ofn.nMaxFileTitle = MAX_PATH ; ofn.lpstrInitialDir = NULL ; ofn.lpstrTitle = NULL ; ofn.Flags = 0 ; ofn.nFileOffset = 0 ; ofn.nFileExtension = 0 ; ofn.lpstrDefExt = TEXT ("bmp") ; ofn.lCustData = 0 ; ofn.lpfnHook = NULL ; ofn.lpTemplateName = NULL ; // Create the All-Purpose Palette hdc = GetDC (hwnd) ; hPalette = CreateHalftonePalette (hdc) ; ReleaseDC (hwnd, hdc) ; return 0 ; case WM_SIZE: cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; return 0 ; case WM_COMMAND: switch (LOWORD (wParam)) { case IDM_FILE_OPEN: // Show the File Open dialog box if (!GetOpenFileName (&ofn)) return 0 ; // If there's an existing packed DIB, free the memory if (pPackedDib) { free (pPackedDib) ; pPackedDib = NULL ; } // Load the packed DIB into memory SetCursor (LoadCursor (NULL, IDC_WAIT)) ; ShowCursor (TRUE) ; pPackedDib = PackedDibLoad (szFileName) ; ShowCursor (FALSE) ; SetCursor (LoadCursor (NULL, IDC_ARROW)) ; if (!pPackedDib) { MessageBox ( hwnd, TEXT ("Cannot load DIB file"), szAppName, 0) ; } InvalidateRect (hwnd, NULL, TRUE) ; return 0 ; } break ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; if (pPackedDib) { // Set halftone stretch mode SetStretchBltMode (hdc, HALFTONE) ; SetBrushOrgEx (hdc, 0, 0, NULL) ; // Select and realize halftone palette SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; // StretchDIBits rather than SetDIBitsToDevice StretchDIBits ( hdc,0,0,PackedDibGetWidth (pPackedDib), PackedDibGetHeight (pPackedDib), 0,0,PackedDibGetWidth (pPackedDib), PackedDibGetHeight (pPackedDib), PackedDibGetBitsPtr (pPackedDib), pPackedDib, DIB_RGB_COLORS, SRCCOPY) ; } EndPaint (hwnd, &ps) ; return 0 ; case WM_QUERYNEWPALETTE: hdc = GetDC (hwnd) ; SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; InvalidateRect (hwnd, NULL, TRUE) ; ReleaseDC (hwnd, hdc) ; return TRUE ; case WM_PALETTECHANGED: if ((HWND) wParam != hwnd) hdc = GetDC (hwnd) ; SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; UpdateColors (hdc) ; ReleaseDC (hwnd, hdc) ; break ; case WM_DESTROY: if (pPackedDib) free (pPackedDib) ; DeleteObject (hPalette) ; PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
SHOWDIB5.RC ��ժ¼�� //Microsoft Developer Studio generated resource script. #include "resource.h" #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// // Menu SHOWDIB5 MENU DISCARDABLE BEGIN POPUP "&Open" BEGIN MENUITEM "&File", IDM_FILE_OPEN END END
RESOURCE.H ��ժ¼�� // Microsoft Developer Studio generated include file. // Used by ShowDib5.rc #define IDM_FILE_OPEN 40001
SHOWDIB5��ʽ�����SHOWDIB4��SHOWDIB4�в�ʹ��DIB�е���ɫ������ʹ�������ͼ��Χ����ĵ�ɫ�̡�Ϊ�ˣ�SHOWDIB5ʹ������Windows֧Ԯ���߼���ɫ�̣�����ſ��Դ�CreateHalftonePalette��ʽ��á�
�м�ɫ��ɫ�̲�����SHOWDIB4�е�CreateAllPurposePalette��ʽ�������ĵ�ɫ�̸����ӡ���ȷ�����ֻ���������ã���������Ƶġ�Ȼ�����������������������ʽ��
SetStretchBltMode (hdc, HALFTONE) ; SetBrushOrgEx (hdc, x, y, NULL) ;
����x��y��DIB���Ͻǵ�װ�����꣬�����������StretchDIBits������SetDIBitsToDevice����ʾDIB����ô����������Ծ�����ɫɫ��Ҫ�Ȳ��趨����ͼ����ģʽ��ʹ��CreateAllPurposePalette����CreateHalftonePalette����ȷ��Windowsʹ��һ�ֻ�ɫͼ���������м�ɫ��ɫ���ϵ���ɫ����ʹ����ӽ�8λԪ��ʾ����Ôʼͼ�����ɫ�������������һ������������ȱ������Ҫ����Ĵ���ʱ�䡣
������ɫ����ɫ
��
���ڿ�ʼ����SetDIBitsToDevice��StretchDIBits��CreateDIBitmap��SetDIBits��GetDIBits��CreateDIBSection��fClrUse������ͨ����������������趨ΪDIB_RGB_COLORS�����0������������Ҳ�ܽ����趨ΪDIB_PAL_COLORS������������£��ٶ�BITMAPINFO�ṹ�е���ɫ��������RGB��ɫֵ�����ǰ����߼���ɫ������ɫ��Ŀ��16λԪ�������߼���ɫ������Ϊ��һ���������ݸ���ʽ��װ��������Ŀǰѡ����Ǹ���ʵ���ϣ���CreateDIBSection�У�֮������Ҫָ��һ����NULL��װ�����ݴ�����Ϊ��һ��������ֻ����Ϊʹ����DIB_PAL_COLORS��
DIB_PAL_COLORS��Ϊ����Щʲô�أ����������һЩ���ܡ�����һ����8λԪ��ʾģʽ�º���SetDIBitsToDevice��ʾ��8λԪDIB��Windows���ȱ�����DIB��ɫ����������ɫ���������豸������ɫ��ӽ�����ɫ��Ȼ���趨һ��С�����Ա㽫DIBͼ��ֵӳ�䵽�豸ͼ�ء�Ҳ����˵�������Ҫ����256����ӽ�����ɫ���������DIB��ɫ���к��д�װ��������ѡ����ɫ���߼���ɫ����Ŀ��������ô�Ϳ�������������
����ʹ�õ�ɫ���������⣬��ʽ16-16��ʾ��SHOWDIB6��ʽ��SHOWDIB3���ơ�
��ʽ16-16 SHOWDIB6 SHOWDIB6.C /*--------------------------------------------------------------------------- SHOWDIB6.C -- Display DIB with palette indices (c) Charles Petzold, 1998 ----------------------------------------------------------------------------*/ #include <windows.h> #include "..\\ShowDib3\\PackeDib.h" #include "resource.h" LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; TCHAR szAppName[] = TEXT ("ShowDib6") ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = szAppName ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox ( NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow ( szAppName, TEXT ("Show DIB #6: Palette Indices"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam) { static BITMAPINFO * pPackedDib ; static HPALETTE hPalette ; static int cxClient, cyClient ; 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") ; HDC hdc ; int i, iNumColors ; PAINTSTRUCT ps ; WORD * pwIndex ; switch (message) { case WM_CREATE: ofn.lStructSize = sizeof (OPENFILENAME) ; ofn.hwndOwner = hwnd ; ofn.hInstance = NULL ; ofn.lpstrFilter = szFilter ; ofn.lpstrCustomFilter = NULL ; ofn.nMaxCustFilter = 0 ; ofn.nFilterIndex = 0 ; ofn.lpstrFile = szFileName ; ofn.nMaxFile = MAX_PATH ; ofn.lpstrFileTitle = szTitleName ; ofn.nMaxFileTitle = MAX_PATH ; ofn.lpstrInitialDir = NULL ; ofn.lpstrTitle = NULL ; ofn.Flags = 0 ; ofn.nFileOffset = 0 ; ofn.nFileExtension = 0 ; ofn.lpstrDefExt = TEXT ("bmp") ; ofn.lCustData = 0 ; ofn.lpfnHook = NULL ; ofn.lpTemplateName = NULL ; return 0 ; case WM_SIZE: cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; return 0 ; case WM_COMMAND: switch (LOWORD (wParam)) { case IDM_FILE_OPEN: // Show the File Open dialog box if (!GetOpenFileName (&ofn)) return 0 ; // If there's an existing packed DIB, free the memory if (pPackedDib) { free (pPackedDib) ; pPackedDib = NULL ; } // If there's an existing logical palette, delete it if (hPalette) { DeleteObject (hPalette) ; hPalette = NULL ; } // Load the packed DIB into memory SetCursor (LoadCursor (NULL, IDC_WAIT)) ; ShowCursor (TRUE) ; pPackedDib = PackedDibLoad (szFileName) ; ShowCursor (FALSE) ; SetCursor (LoadCursor (NULL, IDC_ARROW)) ; if (pPackedDib) { // Create the palette from the DIB color table hPalette = PackedDibCreatePalette (pPackedDib) ; // Replace DIB color table with indices if (hPalette) { iNumColors = PackedDibGetNumColors (pPackedDib) ; pwIndex = (WORD *) PackedDibGetColorTablePtr (pPackedDib) ; for (i = 0 ; i < iNumColors ; i++) pwIndex[i] = (WORD) i ; } } else { MessageBox ( hwnd, TEXT ("Cannot load DIB file"), szAppName, 0) ; } InvalidateRect (hwnd, NULL, TRUE) ; return 0 ; } break ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; if (hPalette) { SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; } if (pPackedDib) SetDIBitsToDevice (hdc,0,0,PackedDibGetWidth (pPackedDib), PackedDibGetHeight (pPackedDib), 0,0,0,PackedDibGetHeight (pPackedDib), PackedDibGetBitsPtr (pPackedDib), pPackedDib, DIB_PAL_COLORS) ; EndPaint (hwnd, &ps) ; return 0 ; 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) break ; hdc = GetDC (hwnd) ; SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; UpdateColors (hdc) ; ReleaseDC (hwnd, hdc) ; break ; case WM_DESTROY: if (pPackedDib) free (pPackedDib) ; if (hPalette) DeleteObject (hPalette) ; PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
SHOWDIB6.RC ��ժ¼�� //Microsoft Developer Studio generated resource script. #include "resource.h" #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// // Menu SHOWDIB6 MENU DISCARDABLE BEGIN POPUP "&File" BEGIN MENUITEM "&Open", IDM_FILE_OPEN END END
RESOURCE.H ��ժ¼�� // Microsoft Developer Studio generated include file. // Used by ShowDib6.rc // #define IDM_FILE_OPEN 40001
SHOWDIB6��DIB���뵽�����岢�ɴ˽����˵�ɫ�����ᣬSHOWDIB6�򵥵�����0��ʼ��WORD�����滻��DIB��ɫ���е���ɫ��PackedDibGetNumColors��ʽ����ʾ�ж�������ɫ����PackedDibGetColorTablePtr��ʽ����ָ��DIB��ɫ����ʼλ�õ�ָ�ꡣ
ע�⣬ֻ��ֱ�Ӵ�DIB��ɫ����������ɫ��ʱ���˼����ſ��С����ʹ��ͨ�õ�ɫ�̣������������ӽ�����ɫ���Ի�÷���DIB��������
���Ҫʹ�õ�ɫ����������ô���ڽ�DIB���浽��Ƭ֮ǰ��ȷʵ�滻��DIB�е���ɫ�������⣬��Ҫ��������ɫ��������DIB�����������ʵ���ϣ�����ʾ֮ǰ������ɫ����������DIB��Ȼ�ὫRGB��ɫֵ�Żأ������ȫһЩ��
��ɫ�̺͵���ͼ���
��
��ʽ16-17�е�SHOWDIB7��ʽ��ʾ�����ʹ����DIB������ĵ�ɫ�̣���ЩDIB��ʹ��CreateDIBitmap��ʽת����GDI����ͼ����ġ�
��ʽ16-17 SHOWDIB7 SHOWDIB7.C /*-------------------------------------------------------------------------- SHOWDIB7.C -- Shows DIB converted to DDB (c) Charles Petzold, 1998 ----------------------------------------------------------------------------*/ #include <windows.h> #include "..\\ShowDib3\\PackeDib.h" #include "resource.h" LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; TCHAR szAppName[] = TEXT ("ShowDib7") ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = szAppName ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox ( NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow ( szAppName, TEXT ("Show DIB #7: Converted to DDB"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HBITMAP hBitmap ; static HPALETTE hPalette ; static int cxClient, cyClient ; 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") ; BITMAP bitmap ; BITMAPINFO * pPackedDib ; HDC hdc, hdcMem ; PAINTSTRUCT ps ; switch (message) { case WM_CREATE: ofn.lStructSize = sizeof (OPENFILENAME) ; ofn.hwndOwner = hwnd ; ofn.hInstance = NULL ; ofn.lpstrFilter = szFilter ; ofn.lpstrCustomFilter = NULL ; ofn.nMaxCustFilter = 0 ; ofn.nFilterIndex = 0 ; ofn.lpstrFile = szFileName ; ofn.nMaxFile = MAX_PATH ; ofn.lpstrFileTitle = szTitleName ; ofn.nMaxFileTitle = MAX_PATH ; ofn.lpstrInitialDir = NULL ; ofn.lpstrTitle = NULL ; ofn.Flags = 0 ; ofn.nFileOffset = 0 ; ofn.nFileExtension = 0 ; ofn.lpstrDefExt = TEXT ("bmp") ; ofn.lCustData = 0 ; ofn.lpfnHook = NULL ; ofn.lpTemplateName = NULL ; return 0 ; case WM_SIZE: cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; return 0 ; case WM_COMMAND: switch (LOWORD (wParam)) { case IDM_FILE_OPEN: // Show the File Open dialog box if (!GetOpenFileName (&ofn)) return 0 ; // If there's an existing packed DIB, free the memory if (hBitmap) { DeleteObject (hBitmap) ; hBitmap = NULL ; } // If there's an existing logical palette, delete it if (hPalette) { DeleteObject (hPalette) ; hPalette = NULL ; } // Load the packed DIB into memory SetCursor (LoadCursor (NULL, IDC_WAIT)) ; ShowCursor (TRUE) ; pPackedDib = PackedDibLoad (szFileName) ; ShowCursor (FALSE) ; SetCursor (LoadCursor (NULL, IDC_ARROW)) ; if (pPackedDib) { // Create palette from the DIB and select it into DC hPalette = PackedDibCreatePalette (pPackedDib) ; hdc = GetDC (hwnd) ; if (hPalette) { SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; } // Create the DDB from the DIB hBitmap = CreateDIBitmap(hdc,(PBITMAPINFOHEADER) pPackedDib, CBM_INIT,PackedDibGetBitsPtr (pPackedDib), pPackedDib, DIB_RGB_COLORS) ; ReleaseDC (hwnd, hdc) ; // Free the packed-DIB memory free (pPackedDib) ; } else { MessageBox ( hwnd, TEXT ("Cannot load DIB file"), szAppName, 0) ; } InvalidateRect (hwnd, NULL, TRUE) ; return 0 ; } break ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; if (hPalette) { SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; } if (hBitmap) { GetObject (hBitmap, sizeof (BITMAP), &bitmap) ; hdcMem = CreateCompatibleDC (hdc) ; SelectObject (hdcMem, hBitmap) ; BitBlt (hdc,0,0,bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY) ; DeleteDC (hdcMem) ; } EndPaint (hwnd, &ps) ; return 0 ; 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) break ; hdc = GetDC (hwnd) ; SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; UpdateColors (hdc) ; ReleaseDC (hwnd, hdc) ; break ; case WM_DESTROY: if (hBitmap) DeleteObject (hBitmap) ; if (hPalette) DeleteObject (hPalette) ; PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
SHOWDIB7.RC ��ժ¼�� //Microsoft Developer Studio generated resource script. #include "resource.h" #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// // Menu SHOWDIB7 MENU DISCARDABLE BEGIN POPUP "&File" BEGIN MENUITEM "&Open", IDM_FILE_OPEN END END
RESOURCE.H ��ժ¼�� // Microsoft Developer Studio generated include file. // Used by ShowDib7.rc #define IDM_FILE_OPEN 40001
��ǰ��ij�ʽһ����SHOWDIB7�����һ��ָ��packed DIB��ָ�꣬��DIB��Ӧ���ܱ��ġ�File������Open�������ʽ��packed DIB�����˵�ɫ�̣�Ȼ�á£ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½WM_COMMANDѶϢ�Ĵ��������У�����������Ѷ��ʾ��װ�����ݣ���ѡ����ɫ�̣����ֵ�ɫ�̡�Ȼ��SHOWDIB7����CreateDIBitmap�Ա��DIB����DDB�������ɫ��û��ѡ��װ�����ݲ����֣���ôCreateDIBitmap������DDB����ʹ���߼���ɫ���еĸ�����ɫ��
����CreateDIBitmap���ᣬ�ó�ʽ���ͷ�packed DIBռ�õļ�����ռ䡣pPackedDib�������Ǿ�̬�������෴�ģ�SHOWDIB7����̬���������˵���ͼ���ţ�hBitmap�����߼���ɫ�̴��ţ�hPalette����
��WM_PAINTѶϢ�����ڼ䣬��ɫ���ٴ�ѡ��װ�����ݲ����֡�GetObject��ʽ�ɻ�õ���ͼ�Ŀ��Ⱥ͸߶ȡ�Ȼ�ᣬ��ʽͨ���������ݵļ�����װ����������ʾ������ʾ����ͼ��ѡ������ͼ����ִ��BitBlt����ʾDDBʱ���õĵ�ɫ�̣��������CreateDIBitmap���н���ʱ���õ�һ����
���������ͼ���Ƶ��������������ʹ��packed DIB��ʽ��Ȼ��Windows���Խ�����ͼ����ṩ��ϣ��ʹ����Щ����ͼ�ij�ʽ��Ȼ���������Ҫ������ͼ������Ƶ���������������Ҫ�����Ѷװ�����ݲ����ֵ�ɫ�̡�������Windows����Ŀǰ��ϵͳ��ɫ�̽�DDBת��ΪDIB��
��ɫ�̺�DIB����
��
���ᣬ��ʽ16-18��ʾ��SHOWDIB8˵�������ʹ�ô���DIB����ĵ�ɫ�̡�
��ʽ16-18 SHOWDIB8 SHOWDIB8.C /*-------------------------------------------------------------------------- SHOWDIB8.C -- Shows DIB converted to DIB section (c) Charles Petzold, 1998 ---------------------------------------------------------------------------*/ #include <windows.h> #include "..\\ShowDib3\\PackeDib.h" #include "resource.h" LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; TCHAR szAppName[] = TEXT ("ShowDib8") ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = szAppName ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox ( NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow ( szAppName, TEXT ("Show DIB #8: DIB Section"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HBITMAP hBitmap ; static HPALETTE hPalette ; static int cxClient, cyClient ; static OPENFILENAME ofn ; static PBYTE pBits ; static TCHAR szFileName [MAX_PATH], szTitleName [MAX_PATH] ; static TCHAR szFilter[] = TEXT ("Bitmap Files (*.BMP)\0*.bmp\0") TEXT ("All Files (*.*)\0*.*\0\0") ; BITMAP bitmap ; BITMAPINFO * pPackedDib ; HDC hdc, hdcMem ; PAINTSTRUCT ps ; switch (message) { case WM_CREATE: ofn.lStructSize = sizeof (OPENFILENAME) ; ofn.hwndOwner = hwnd ; ofn.hInstance = NULL ; ofn.lpstrFilter = szFilter ; ofn.lpstrCustomFilter = NULL ; ofn.nMaxCustFilter = 0 ; ofn.nFilterIndex = 0 ; ofn.lpstrFile = szFileName ; ofn.nMaxFile = MAX_PATH ; ofn.lpstrFileTitle = szTitleName ; ofn.nMaxFileTitle = MAX_PATH ; ofn.lpstrInitialDir = NULL ; ofn.lpstrTitle = NULL ; ofn.Flags = 0 ; ofn.nFileOffset = 0 ; ofn.nFileExtension = 0 ; ofn.lpstrDefExt = TEXT ("bmp") ; ofn.lCustData = 0 ; ofn.lpfnHook = NULL ; ofn.lpTemplateName = NULL ; return 0 ; case WM_SIZE: cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; return 0 ; case WM_COMMAND: switch (LOWORD (wParam)) { case IDM_FILE_OPEN: // Show the File Open dialog box if (!GetOpenFileName (&ofn)) return 0 ; // If there's an existing packed DIB, free the memory if (hBitmap) { DeleteObject (hBitmap) ; hBitmap = NULL ; } // If there's an existing logical palette, delete it if (hPalette) { DeleteObject (hPalette) ; hPalette = NULL ; } // Load the packed DIB into memory SetCursor (LoadCursor (NULL, IDC_WAIT)) ; ShowCursor (TRUE) ; pPackedDib = PackedDibLoad (szFileName) ; ShowCursor (FALSE) ; SetCursor (LoadCursor (NULL, IDC_ARROW)) ; if (pPackedDib) { // Create the DIB section from the DIB hBitmap = CreateDIBSection (NULL,pPackedDib,DIB_RGB_COLORS,&pBits,NULL, 0) ; // Copy the bits CopyMemory (pBits, PackedDibGetBitsPtr (pPackedDib), PackedDibGetBitsSize (pPackedDib)) ; // Create palette from the DIB hPalette = PackedDibCreatePalette (pPackedDib) ; // Free the packed-DIB memory free (pPackedDib) ; } else { MessageBox ( hwnd, TEXT ("Cannot load DIB file"), szAppName, 0) ; } InvalidateRect (hwnd, NULL, TRUE) ; return 0 ; } break ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; if (hPalette) { SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; } if (hBitmap) { GetObject (hBitmap, sizeof (BITMAP), &bitmap) ; hdcMem = CreateCompatibleDC (hdc) ; SelectObject (hdcMem, hBitmap) ; BitBlt ( hdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY) ; DeleteDC (hdcMem) ; } EndPaint (hwnd, &ps) ; return 0 ; 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) break ; hdc = GetDC (hwnd) ; SelectPalette (hdc, hPalette, FALSE) ; RealizePalette (hdc) ; UpdateColors (hdc) ; ReleaseDC (hwnd, hdc) ; break ; case WM_DESTROY: if (hBitmap) DeleteObject (hBitmap) ; if (hPalette) DeleteObject (hPalette) ; PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
SHOWDIB8.RC ��ժ¼�� //Microsoft Developer Studio generated resource script. #include "resource.h" #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// // Menu SHOWDIB8 MENU DISCARDABLE BEGIN POPUP "&File" BEGIN MENUITEM "&Open", IDM_FILE_OPEN END END
RESOURCE.H ��ժ¼�� // Microsoft Developer Studio generated include file. // Used by ShowDib8.rc #define IDM_FILE_OPEN 40001
��SHOWDIB7��SHOWDIB8�е�WM_PAINT������һ���ģ�������ʽ��������ͼ���ţ�hBitmap�����߼���ɫ�̴��ţ�hPalette����Ϊ��̬��������ɫ�̱�ѡ��װ�����ݲ����֣�����ͼ�Ŀ��Ⱥ͸߶ȴ�GetObject��ʽ��ã���ʽ����������װ�����ݲ�ѡ������ͼ��Ȼ��ͨ������BitBlt������ͼ��ʾ����ʾ����
������ʽ֮�����IJ����춴�����File������Open�����ܱ�����ij����ڻ��ָ��packed DIB��ָ�겢�����˵�ɫ�����ᣬSHOWDIB7���뽫��ɫ��ѡ����Ѷװ�����ݣ����ں���CreateDIBitmap֮ǰ���֡�SHOWDIB8�ڻ��packed DIBָ���������CreateDIBSection�����ؽ���ɫ��ѡ��װ�����ݣ�������ΪCreateDIBSection����DIBת�����豸��صĸ�ʽ����ȷ��CreateDIBSection�ĵ�һ����������װ�����ݴ��ţ���Ψһ��;������Ƿ�ʹ��DIB_PAL_COLORS��ꡣ
����CreateDIBSection���ᣬSHOWDIB8��ͼ��λԪ��packed DIB���Ƶ���CreateDIBSection��ʽ���صļ�����λ�ã�Ȼ�����PackedDibCreatePalette�����ܴ˺�ʽ��춳�ʽʹ�ã�����SHOWDIB8�����ݴ�GetDIBColorTable��ʽ���ص���Ѷ������ɫ�̡�
DIB������ʽ��
��
�������ڣ��������dz�ʱ���ѧϰGDI����ͼ�����װ���޹ص���ͼ��DIB�����Windows��ɫ�̹�����֮�á£ï¿½ï¿½ï¿½Ç²ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ë¿ï¿½ï¿½ï¿½Ò»ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ì¶´ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Í¼ï¿½Äºï¿½Ê½ï¿½ï¿½×¼ï¿½ï¿½ï¿½ï¿½
ǰ���PACKEDIB����չʾ��һ�ֿ��ܵķ������������е�packed DIBֻ��ָ������ָ���ʾ����ʽ�����й�DIB��ȫ����Ѷ�����ԴӴ�ȡ��ͷ��Ѷ�ṹ�ĺ�ʽ��á�Ȼ����ʵ���ϵ���get pixel���͡�set pixel����ʽʱ�����ַ����ͻ�������ص�ִ�����⡣ͼ��������Ȼ��Ҫ��ȡ����ͼλԪ��������Щ��ʽҲӦ�þ����ܵؿ졣
���ܵ�C++�Ľ����ʽ�а�������DIB�����ʱָ��packed DIB��ָ��������һ����Ա������������Ա�����ͳ�Ա��ʽ����춸����ִ�л�ú��趨DIB�е�ͼ�صij�ʽ����������Ϊ���ڵ�һ���Ѿ�ָ������춱�����ֻ��Ҫ�˽�C��ʹ��C++����������ķ�Χ��
��Ȼ����C++������������CҲ������һ���õ����Ӿ�������Windows��ʽ��ʹ�ô��š����˽����ŵ�����ֵ���⣬Ӧ�ó�ʽ�������˽�ʲô�أ���ʽ֪��������������ĺ�ʽ�������֪����ʽ��춴����ִ���������Ȼ����ҵϵͳ��ij�ַ�ʽ�ô���������������ڲ���Ѷ�����ſ�����ṹָ��һ���򵥡�
���磬������һ����ʽ������Щ��ʽ��ʹ��һ����ΪHDIB�Ĵ��š�HDIB��ʲô�أ���������ij����ͷ�����ж������£�
typedef void * HDIB ;
�˶����á����������¡��ش��ˡ�HDIB��ʲô��������⡣
Ȼ����ʵ����HDIB�����ǽṹָ�꣬�ýṹ��������ָ��packed DIB��ָ�꣬������������Ѷ��
typedef struct { BITMAPINFO * pPackedDib ; int cx, cy, cBitsPerPixel, cBytesPerRow ; BYTE * pBits ; { DIBSTRUCTURE, * PDIBSTRUCTURE ;
�˽ṹ�����������λ������packed DIB����������Ѷ����Ȼ���ṹ����Щֵ���������ٵش�ȡ���ǡ���ͬ��DIB��ʽ�⺯ʽ�����Դ�������ṹ��������pPackedDibָ�ꡣ���԰�����ķ�����ִ��DibGetPixelPointer��ʽ��
BYTE * DibGetPixelPointer (HDIB hdib, int x, int y) { PDIBSTRUCTURE pdib = hdib ; return pdib->pBits + y * pdib->cBytesPerRow + x * pdib->cBitsPerPixel / 8 ; }
��Ȼ�����ַ�������Ҫ��PACKEDIB.C��ִ�С�get pixel����ʽ�졣
������ַ����dz������������Ҿ�������packed DIB�������ô���DIB�����DIB��ʽ�⡣��ʵ����ʹ���Ƕ�packed DIB�Ĵ����и���ĵ��ԣ�Ҳ����˵���ܹ���װ���޹صķ�ʽ�²���DIBͼ��λԪ����������Windows NT��ִ��ʱ������Ч��
DIBSTRUCT�ṹ
��
DIBHELP.C�����������������Ϊ�Դ���DIB�ṩ����������ǧ�У����ڼ���С��������ʾ���������������ǿ�һ��DIBHELP��ʽ�������Ľṹ���ýṹ��DIBHELP.C�ж������£�
typedef struct { PBYTE * ppRow ; // array of row pointers int iSignature ; // = "Dib " HBITMAP hBitmap ; // handle returned from CreateDIBSection BYTE * pBits ; // pointer to bitmap bits DIBSECTION ds ; // DIBSECTION structure int iRShift[3] ; // right-shift values for color masks int iLShift[3] ; // left-shift values for color masks } DIBSTRUCT, * PDIBSTRUCT ;
����������һ����λ����֮����Ϊ��һ����λ����Ϊ��ʹijЩ�޼������ʹ�ã���������������λ�������������һ����λ�͸������ˡ�
��DIBHELP.C�У���DIB�����ĺ�ʽ�����趨�˴˽ṹʱ���ڶ�����λ���趨Ϊ�����ִ���Dib���Ķ���λֵ��ͨ��һЩDIBHELP��ʽ���ڶ�����λ����춽ṹ��Чָ���һ����ǡ�
��������λ����hBitmap���Ǵ�CreateDIBSection��ʽ���صĵ���ͼ���š���������ô��ſ��ж���ʹ�÷�ʽ�����������ڵ�ʮ����������GDI����ͼ����Ĵ����÷�һ������������CreateDIBSection���صĴ��Ž��漰��װ���޹ظ�ʽ����ĵ���ͼ���õ���ͼ��ʽһֱ���浽ͨ������BitBlt��StretchBlt����λԪͼ��������豸��
DIBSTRUCT�ĵ��ĸ���λ��ָ�����ͼλԪ��ָ�ꡣ��ֵҲ����CreateDIBSection��ʽ�趨������������ҵϵͳ���������������飬��Ӧ�ó�ʽ�д�ȡ��������Ȩ����ɾ������ͼ����ʱ��������齫�Զ��ͷš�
DIBSTRUCT�ĵ������λ��DIBSECTION�ṹ��������д�CreateDIBSection���صĵ���ͼ���ţ���ô�����Խ����Ŵ��ݸ�GetObject��ʽ�Ի���й�DIBSECTION�ṹ�еĵ���ͼ��Ѷ��
GetObject (hBitmap, sizeof (DIBSECTION), &ds) ;
��Ϊ��ʾ��DIBSECTION�ṹ��WINGDI.H�ж������£�
typedef struct tagDIBSECTION { BITMAP dsBm ; BITMAPINFOHEADER dsBmih ; DWORD dsBitfields[3] ; // Color masks HANDLE dshSection ; DWORD dsOffset ; } DIBSECTION, * PDIBSECTION ;
��һ����λ��BITMAP�ṹ������CreateBitmapIndirectһ��������ͼ�������GetObjectһ�𴫻ع��DDB����Ѷ���ڶ�����λ��BITMAPINFOHEADER�ṹ�����ܵ���ͼ��Ѷ�ṹ�Ƿ񴫵ݸ�CreateDIBSection��ʽ��DIBSECTION�ṹ����BITMAPINFOHEADER�ṹ�����������ṹ������BITMAPCOREHEADER�ṹ������ζ���ڴ�ȡ�˽ṹʱ��DIBHELP.C�е����ຯʽ�����ؼ����OS/2���ݵ�DIB��
���16λԪ��32λԪ��DIB�����BITMAPINFOHEADER�ṹ��biCompression��λ��BI_BITFIELDS����ô����Ѷ��ͷ�ṹ����ͨ������������ֵ����Щ����ֵ������ν�16λԪ��32λͼ��ֵת����RGB��ɫ�����ִ�����DIBSECTION�ṹ�ĵ�������λ�С�
DIBSECTION�ṹ������������λָ����DIB���飬�������ɵ���ӳ�佨����DIBHELP��ʹ��CreateDIBSection��������ԣ���˿��Ժ�����Щ��λ��
DIBSTRUCT������������λ����������λֵ����Щֵ��춴���16λԪ��32λԪDIB����ɫ���֡����ǽ��ڵ�ʮ����������Щ��λֵ��
�������ٻ�����һ��DIBSTRUCT�ĵ�һ����λ������������������һ�����ڿ�ʼ����DIBʱ������λ�趨Ϊָ��һ��ָ�����е�ָ�꣬�������е�ÿ��ָ�궼ָ��DIB�е�һ��ͼ�ء���Щָ�������Ը���ķ�ʽ�����DIBͼ��λԪ��ͬʱҲ�����壬�Ա㶥�п�����������DIBͼ��λԪ�������е�����һ��Ԫ�أ�����DIBͼ�������У�ͨ�����DIBSTRUCT��pBits��λ��
��Ѷ��ʽ
��
DIBHELP.C�Զ���DIBSTRUCT�ṹ��ʼ��Ȼ���ṩһ����ʽ�����˺�ʽ������Ӧ�ó�ʽ����й�DIB�������Ѷ����ʽ16-19��ʾ��DIBHELP.C�ĵ�һ���֡�
��ʽ16-19 DIBHELP.C�����ĵ�һ���� 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 ; // must be first field for macros! int iSignature ; HBITMAP hBitmap ; BYTE * pBits ; DIBSECTION ds ; int iRShift[3] ; int iLShift[3] ; } DIBSTRUCT, * PDIBSTRUCT ; /*---------------------------------------------------------------------------- DibIsValid: Returns TRUE if hdib points to a valid DIBSTRUCT -----------------------------------------------------------------------------*/ BOOL DibIsValid (HDIB hdib) { PDIBSTRUCT pdib = hdib ; if (pdib == NULL) return FALSE ; if (IsBadReadPtr (pdib, sizeof (DIBSTRUCT))) return FALSE ; if (pdib->iSignature != HDIB_SIGNATURE) return FALSE ; return TRUE ; } /*---------------------------------------------------------------------------- DibBitmapHandle: Returns the handle to the DIB section bitmap object -----------------------------------------------------------------------------*/ HBITMAP DibBitmapHandle (HDIB hdib) { if (!DibIsValid (hdib)) return NULL ; return ((PDIBSTRUCT) hdib)->hBitmap ; } /*--------------------------------------------------------------------------- DibWidth: Returns the bitmap pixel width -----------------------------------------------------------------------------*/ int DibWidth (HDIB hdib) { if (!DibIsValid (hdib)) return 0 ; return ((PDIBSTRUCT) hdib)->ds.dsBm.bmWidth ; } /*--------------------------------------------------------------------------- DibHeight: Returns the bitmap pixel height ----------------------------------------------------------------------------*/ int DibHeight (HDIB hdib) { if (!DibIsValid (hdib)) return 0 ; return ((PDIBSTRUCT) hdib)->ds.dsBm.bmHeight ; } /*--------------------------------------------------------------------------- DibBitCount: Returns the number of bits per pixel ----------------------------------------------------------------------------*/ int DibBitCount (HDIB hdib) { if (!DibIsValid (hdib)) return 0 ; return ((PDIBSTRUCT) hdib)->ds.dsBm.bmBitsPixel ; } /*---------------------------------------------------------------------------- DibRowLength: Returns the number of bytes per row of pixels -----------------------------------------------------------------------------*/ int DibRowLength (HDIB hdib) { if (!DibIsValid (hdib)) return 0 ; return 4 * ((DibWidth (hdib) * DibBitCount (hdib) + 31) / 32) ; } /*--------------------------------------------------------------------------- DibNumColors: Returns the number of colors in the color table ----------------------------------------------------------------------------*/ int DibNumColors (HDIB hdib) { PDIBSTRUCT pdib = hdib ; if (!DibIsValid (hdib)) return 0 ; if (pdib->ds.dsBmih.biClrUsed != 0) { return pdib->ds.dsBmih.biClrUsed ; } else if (DibBitCount (hdib) <= 8) { return 1 << DibBitCount (hdib) ; } return 0 ; } /*--------------------------------------------------------------------------- DibMask: Returns one of the color masks ---------------------------------------------------------------------------*/ DWORD DibMask (HDIB hdib, int i) { PDIBSTRUCT pdib = hdib ; if (!DibIsValid (hdib) || i < 0 || i > 2) return 0 ; return pdib->ds.dsBitfields[i] ; } /*---------------------------------------------------------------------------- DibRShift: Returns one of the right-shift values -----------------------------------------------------------------------------*/ int DibRShift (HDIB hdib, int i) { PDIBSTRUCT pdib = hdib ; if (!DibIsValid (hdib) || i < 0 || i > 2) return 0 ; return pdib->iRShift[i] ; } /*---------------------------------------------------------------------------- DibLShift: Returns one of the left-shift values ----------------------------------------------------------------------------*/ int DibLShift (HDIB hdib, int i) { PDIBSTRUCT pdib = hdib ; if (!DibIsValid (hdib) || i < 0 || i > 2) return 0 ; return pdib->iLShift[i] ; } /*--------------------------------------------------------------------------- DibCompression: Returns the value of the biCompression field ----------------------------------------------------------------------------*/ int DibCompression (HDIB hdib) { if (!DibIsValid (hdib)) return 0 ; return ((PDIBSTRUCT) hdib)->ds.dsBmih.biCompression ; } /*--------------------------------------------------------------------------- DibIsAddressable: Returns TRUE if the DIB is not compressed ----------------------------------------------------------------------------*/ BOOL DibIsAddressable (HDIB hdib) { int iCompression ; if (!DibIsValid (hdib)) return FALSE ; iCompression = DibCompression (hdib) ; if ( iCompression == BI_RGB || iCompression == BI_BITFIELDS) return TRUE ; return FALSE ; } /*--------------------------------------------------------------------------- These functions return the sizes of various components of the DIB section AS THEY WOULD APPEAR in a packed DIB. These functions aid in converting the DIB section to a packed DIB and in saving DIB files. -----------------------------------------------------------------------------*/ DWORD DibInfoHeaderSize (HDIB hdib) { if (!DibIsValid (hdib)) return 0 ; return ((PDIBSTRUCT) hdib)->ds.dsBmih.biSize ; } DWORD DibMaskSize (HDIB hdib) { PDIBSTRUCT pdib = hdib ; if (!DibIsValid (hdib)) return 0 ; if (pdib->ds.dsBmih.biCompression == BI_BITFIELDS) return 3 * sizeof (DWORD) ; return 0 ; } 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 0 ; if (pdib->ds.dsBmih.biSizeImage != 0) { return pdib->ds.dsBmih.biSizeImage ; } return DibHeight (hdib) * DibRowLength (hdib) ; } DWORD DibTotalSize (HDIB hdib) { return DibInfoSize (hdib) + DibBitsSize (hdib) ; } /*--------------------------------------------------------------------------- These functions return pointers to the various components of the 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 0 ; return pdib->ds.dsBitfields ; } void * DibBitsPtr (HDIB hdib) { if (!DibIsValid (hdib)) return NULL ; return ((PDIBSTRUCT) hdib)->pBits ; } /*--------------------------------------------------------------------------- DibSetColor: Obtains entry from the DIB color table -----------------------------------------------------------------------------*/ BOOL DibGetColor (HDIB hdib, int index, RGBQUAD * prgb) { PDIBSTRUCT pdib = hdib ; HDC hdcMem ; int iReturn ; if (!DibIsValid (hdib)) return 0 ; hdcMem = CreateCompatibleDC (NULL) ; SelectObject (hdcMem, pdib->hBitmap) ; iReturn = GetDIBColorTable (hdcMem, index, 1, prgb) ; DeleteDC (hdcMem) ; return iReturn ? TRUE : FALSE ; } /*---------------------------------------------------------------------------- DibGetColor: Sets an entry in the DIB color table ----------------------------------------------------------------------------*/ BOOL DibSetColor (HDIB hdib, int index, RGBQUAD * prgb) { PDIBSTRUCT pdib = hdib ; HDC hdcMem ; int iReturn ; if (!DibIsValid (hdib)) return 0 ; hdcMem = CreateCompatibleDC (NULL) ; SelectObject (hdcMem, pdib->hBitmap) ; iReturn = SetDIBColorTable (hdcMem, index, 1, prgb) ; DeleteDC (hdcMem) ; return iReturn ? TRUE : FALSE ; }
DIBHELP.C�еĴ󲿷ֺ�ʽ�Dz��ý��͵ġ�DibIsValid��ʽ������춱�������ϵͳ������ͼ����DIBSTRUCT�е���Ѷ֮ǰ��������ʽ������DibIsValid��������Щ��ʽ���У�����ͨ����ֻ�У�HDIB��̬�ĵ�һ��������( ���ǽ������������ò�����DIBHELP.H�ж���Ϊ��ָ�ꡣ��Щ��ʽ���Խ��˲������浽PDIBSTRUCT��Ȼ���ٴ�ȡ�ṹ�е���λ��
ע�⴫��BOOLֵ��DibIsAddressable��ʽ��DibIsNotCompressed��ʽҲ���Ժ��д˺�ʽ������ֵ��ʾ������DIBͼ���ܷ�ַ��
��DibInfoHeaderSize��ʼ�ĺ�ʽ����ȡ��DIB�����в�ͬԪ��������packed DIB�еĴ�С����������������һ������Щ��ʽ����춽�DIB����ת����packed DIB��������DIB��������Щ��ʽ�������ǻ��ָ��ͬDIBԪ����ָ��ĺ�ʽ����
����DIBHELP.C��������ΪDibInfoHeaderPtr�ĺ�ʽ�����Ҹú�ʽ�����ָ��BITMAPINFOHEADER�ṹ��ָ�꣬������û�к�ʽ���Ի��BITMAPINFO�ṹָ�ê£ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½DIB��ɫ���������Ѷ�ṹ��������Ϊ�ڴ���DIB����ʱ��Ӧ�ó�ʽ����ֱ�Ӵ�ȡ������̬�Ľṹ��BITMAPINFOHEADER�ṹ����ɫ���ֶ���DIBSECTION�ṹ����Ч�����Ҵ�CreateDIBSection��ʽ����ָ��ͼ��λԪ��ָ�꣬��ʱͨ������GetDIBColorTable��SetDIBColorTable����ֻ�ܼ�Ӵ�ȡDIB��ɫ������Щ���ܶ���װ��DIBHELP��DibGetColor��DibSetColor��ʽ��ͷ�ˡ�
��DIBHELP.C�����棬����DibCopyToInfo����һ��ָ��BITMAPINFO�ṹ��ָ�꣬�������Ѷ������������ָ����������ִ�ṹ��ָ�겻��ȫ��ͬ��
����дͼ��
��
Ӧ�ó�ʽά��packed DIB��DIB�����һ������עĿ���ŵ����ܹ�ֱ�Ӳ���DIBͼ��λԪ����ʽ16-20��ʾ��DIBHELP.C�ڶ������г����ṩ�˹��ܵĺ�ʽ��
��ʽ16-20 DIBHELP.C�����ĵڶ����� DIBHELP.C ���ڶ����֣� /*---------------------------------------------------------------------------- DibPixelPtr: Returns a pointer to the pixel at position (x, y) -----------------------------------------------------------------------------*/ BYTE * DibPixelPtr (HDIB hdib, int x, int y) { if (!DibIsAddressable (hdib)) return NULL ; if (x < 0 || x >= DibWidth (hdib) || y < 0 || y >= DibHeight (hdib)) return NULL ; return (((PDIBSTRUCT) hdib)->ppRow)[y] + (x * DibBitCount (hdib) >> 3) ; } /*--------------------------------------------------------------------------- DibGetPixel: Obtains a pixel value at (x, y) -----------------------------------------------------------------------------*/ DWORD DibGetPixel (HDIB hdib, int x, int y) { PBYTE pPixel ; if (!(pPixel = DibPixelPtr (hdib, x, y))) return 0 ; switch (DibBitCount (hdib)) { case 1: return 0x01 & (* pPixel >> (7 - (x & 7))) ; case 4: return 0x0F & (* pPixel >> (x & 1 ? 0 : 4)) ; case 8: return * pPixel ; case 16: return * (WORD *) pPixel ; case 24: return 0x00FFFFFF & * (DWORD *) pPixel ; case 32: return * (DWORD *) pPixel ; } return 0 ; } /*------------------------------------------------------------------------- DibSetPixel: Sets a pixel value at (x, y) ---------------------------------------------------------------------------*/ BOOL DibSetPixel (HDIB hdib, int x, int y, DWORD dwPixel) { PBYTE pPixel ; if (!(pPixel = DibPixelPtr (hdib, x, y))) return FALSE ; switch (DibBitCount (hdib)) { case 1: * pPixel &= ~(1 << (7 - (x & 7))) ; * pPixel |= dwPixel << (7 - (x & 7)) ; break ; case 4: * pPixel &= 0x0F << (x & 1 ? 4 : 0) ; * pPixel |= dwPixel << (x & 1 ? 0 : 4) ; break ; case 8: * pPixel = (BYTE) dwPixel ; break ; case 16: * (WORD *) pPixel = (WORD) dwPixel ; break ; case 24: * (RGBTRIPLE *) pPixel = * (RGBTRIPLE *) &dwPixel ; break ; case 32: * (DWORD *) pPixel = dwPixel ; break ; default: return FALSE ; } return TRUE ; } /*--------------------------------------------------------------------------- DibGetPixelColor: Obtains the pixel color at (x, y) ----------------------------------------------------------------------------*/ BOOL DibGetPixelColor (HDIB hdib, int x, int y, RGBQUAD * prgb) { DWORD dwPixel ; int iBitCount ; PDIBSTRUCT pdib = hdib ; // Get bit count; also use this as a validity check if (0 == (iBitCount = DibBitCount (hdib))) return FALSE ; // Get the pixel value dwPixel = DibGetPixel (hdib, x, y) ; // If the bit-count is 8 or less, index the color table if (iBitCount <= 8) return DibGetColor (hdib, (int) dwPixel, prgb) ; // If the bit-count is 24, just use the pixel else if (iBitCount == 24) { * (RGBTRIPLE *) prgb = * (RGBTRIPLE *) & dwPixel ; prgb->rgbReserved = 0 ; } // If the bit-count is 32 and the biCompression field is BI_RGB, // just use the pixel else if (iBitCount == 32 && pdib->ds.dsBmih.biCompression == BI_RGB) { * prgb = * (RGBQUAD *) & dwPixel ; } // Otherwise, use the mask and shift values // (for best performance, don't use DibMask and DibShift functions) else { prgb->rgbRed = (BYTE)(((pdib->ds.dsBitfields[0] & dwPixel) >> pdib->iRShift[0]) << pdib->iLShift[0]) ; prgb->rgbGreen=(BYTE((pdib->ds.dsBitfields[1] & dwPixel) >> pdib->iRShift[1]) << pdib->iLShift[1]) ; prgb->rgbBlue=(BYTE)(((pdib->ds.dsBitfields[2] & dwPixel) >> pdib->iRShift[2]) << pdib->iLShift[2]) ; } return TRUE ; } /*----------------------------------------------------------------------------- DibSetPixelColor: Sets the pixel color at (x, y) -----------------------------------------------------------------------------*/ BOOL DibSetPixelColor (HDIB hdib, int x, int y, RGBQUAD * prgb) { DWORD dwPixel ; int iBitCount ; PDIBSTRUCT pdib = hdib ; // Don't do this function for DIBs with color tables iBitCount = DibBitCount (hdib) ; if (iBitCount <= 8) return FALSE ; // The rest is just the opposite of DibGetPixelColor else if (iBitCount == 24) { * (RGBTRIPLE *) & dwPixel = * (RGBTRIPLE *) prgb ; dwPixel &= 0x00FFFFFF ; } else if (iBitCount == 32 && pdib->ds.dsBmih.biCompression == BI_RGB) { * (RGBQUAD *) & dwPixel = * prgb ; } else { dwPixel = (((DWORD) prgb->rgbRed >> pdib->iLShift[0]) << pdib->iRShift[0]) ; dwPixel |= (((DWORD) prgb->rgbGreen >> pdib->iLShift[1]) << pdib->iRShift[1]) ; dwPixel |= (((DWORD) prgb->rgbBlue >> pdib->iLShift[2]) << pdib->iRShift[2]) ; } DibSetPixel (hdib, x, y, dwPixel) ; return TRUE ; }
�ⲿ��DIBHELP.C��DibPixelPtr��ʽ��ʼ���ú�ʽ���ָ�򴢴棨�򲿷ִ��棩������ͼ�ص�λԪ���ָ�ꡣ����һ��DIBSTRUCT�ṹ��ppRow��λ�����Ǹ�ָ��DIB���ɶ��п�ʼ���е�ͼ����λַ��ָ�ꡣ������
((PDIBSTRUCT) hdib)->pprow)[0]
����ָ��DIB���������ͼ�ص�ָ�꣬��
(((PDIBSTRUCT) hdib)->ppRow)[y] + (x * DibBitCount (hdib) >> 3)
��ָ��λ�(x,y)��ͼ�ص�ָ�ꡣע�⣬���DIB�е�ͼ�ز��ɱ���ַ���������ѹ���������������ʽ��x��y�����Ǹ��������λ�DIB�����������ʽ������NULL���˼�齵���˺�ʽ�������������DibPixelPtr�ĺ�ʽ����ִ���ٶȣ������ҽ�����һЩ����ij�ʽ��
���������DibGetPixel��DibSetPixel��ʽ������DibPixelPtr�����8λԪ��16λԪ��32λԪDIB����Щ��ʽֻ��¼ָ��������ϳߴ��ָ�꣬����ȡͼ��ֵ�����1λԪ��4λԪ��DIB������Ҫ���ֺ���λ�Ƕȡ�
DibGetColor��ʽ��RGBQUAD�ṹ���ͼ����ɫ�����1λԪ��4λԪ��8λԪDIB�������ʹ��ͼ��ֵ����DIB��ɫ�������ɫ�����16λԪ��24λԪ��32λԪDIB��ͨ�����뽫ͼ��ֵ���ֺ���λ�Եõ�RGB��ɫ��DibSetPixel��ʽ���෴����������RGBQUAD�ṹ�趨ͼ��ֵ���ú�ʽֻΪ16λԪ��24λԪ��32λԪDIB���塣
������ת��
��
��ʽ16-21��ʾ��DIBHELP�������ֺ����Ჿ��չʾ����ν���DIB���飬�Լ���ν�DIB������packed DIB�໥ת����
��ʽ16-21 DIBHELP.C�����ĵ������ֺ����Ჿ�� DIBHELP.C ���������֣� /*-------------------------------------------------------------------------- Calculating shift values from color masks is required by the DibCreateFromInfo function. ----------------------------------------------------------------------------*/ static int MaskToRShift (DWORD dwMask) { int iShift ; if (dwMask == 0) return 0 ; for (iShift = 0 ; !(dwMask & 1) ; iShift++) dwMask >>= 1 ; return iShift ; } static int MaskToLShift (DWORD dwMask) { int iShift ; if (dwMask == 0) return 0 ; while (!(dwMask & 1)) dwMask >>= 1 ; for (iShift = 0 ; dwMask & 1 ; iShift++) dwMask >>= 1 ; return 8 - iShift ; } /*---------------------------------------------------------------------------- DibCreateFromInfo: All DIB creation functions ultimately call this one. This function is responsible for calling CreateDIBSection, allocating memory for DIBSTRUCT, and setting up the row pointer. -----------------------------------------------------------------------------*/ HDIB DibCreateFromInfo (BITMAPINFO * pbmi) { BYTE * pBits ; DIBSTRUCT * pdib ; HBITMAP hBitmap ; int i, iRowLength, cy, y ; hBitmap = CreateDIBSection (NULL, pbmi, DIB_RGB_COLORS, &pBits, NULL, 0) ; if (hBitmap == NULL) return NULL ; if (NULL == (pdib = malloc (sizeof (DIBSTRUCT)))) { DeleteObject (hBitmap) ; return NULL ; } pdib->iSignature = HDIB_SIGNATURE ; pdib->hBitmap = hBitmap ; pdib->pBits = pBits ; GetObject (hBitmap, sizeof (DIBSECTION), &pdib->ds) ; // Notice that we can now use the DIB information functions // defined above. // If the compression is BI_BITFIELDS, calculate shifts from masks if (DibCompression (pdib) == BI_BITFIELDS) { for (i = 0 ; i < 3 ; i++) { pdib->iLShift[i] = MaskToLShift (pdib->ds.dsBitfields[i]) ; pdib->iRShift[i] = MaskToRShift (pdib->ds.dsBitfields[i]) ; } } // If the compression is BI_RGB, but bit-count is 16 or 32, // set the bitfields and the masks else if (DibCompression (pdib) == BI_RGB) { if (DibBitCount (pdib) == 16) { pdib->ds.dsBitfields[0] = 0x00007C00 ; pdib->ds.dsBitfields[1] = 0x000003E0 ; pdib->ds.dsBitfields[2] = 0x0000001F ; pdib->iRShift [0] = 10 ; pdib->iRShift [1] = 5 ; pdib->iRShift [2] = 0 ; pdib->iLShift [0] = 3 ; pdib->iLShift [1] = 3 ; pdib->iLShift [2] = 3 ; } else if (DibBitCount (pdib) == 24 || DibBitCount (pdib) == 32) { pdib->ds.dsBitfields[0] = 0x00FF0000 ; pdib->ds.dsBitfields[1] = 0x0000FF00 ; pdib->ds.dsBitfields[2] = 0x000000FF ; pdib->iRShift [0] = 16 ; pdib->iRShift [1] = 8 ; pdib->iRShift [2] = 0 ; pdib->iLShift [0] = 0 ; pdib->iLShift [1] = 0 ; pdib->iLShift [2] = 0 ; } } // Allocate an array of pointers to each row in the DIB cy = DibHeight (pdib) ; if (NULL == (pdib->ppRow = malloc (cy * sizeof (BYTE *)))) { free (pdib) ; DeleteObject (hBitmap) ; return NULL ; } // Initialize them. iRowLength = DibRowLength (pdib) ; if (pbmi->bmiHeader.biHeight > 0) // ie, bottom up { for (y = 0 ; y < cy ; y++) pdib->ppRow[y] = pBits + (cy - y - 1) * iRowLength ; } else // top down { for (y = 0 ; y < cy ; y++) pdib->ppRow[y] = pBits + y * iRowLength ; } return pdib ; } /*-------------------------------------------------------------------------- DibDelete: Frees all memory for the DIB section ----------------------------------------------------------------------------*/ BOOL DibDelete (HDIB hdib) { DIBSTRUCT * pdib = hdib ; if (!DibIsValid (hdib)) return FALSE ; free (pdib->ppRow) ; DeleteObject (pdib->hBitmap) ; free (pdib) ; return TRUE ; } /*---------------------------------------------------------------------------- DibCreate: Creates an HDIB from explicit arguments -----------------------------------------------------------------------------*/ HDIB DibCreate (int cx, int cy, int cBits, int cColors) { BITMAPINFO * pbmi ; DWORD dwInfoSize ; HDIB hDib ; int cEntries ; if (cx <= 0 || cy <= 0 || ((cBits != 1) && (cBits != 4) && (cBits != 8) && (cBits != 16) && (cBits != 24) && (cBits != 32))) { return NULL ; } if ( cColors != 0) cEntries = cColors ; else if (cBits <= 8) cEntries = 1 << cBits ; dwInfoSize = sizeof (BITMAPINFOHEADER) + (cEntries - 1) * 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 = 1 ; pbmi->bmiHeader.biBitCount = cBits ; pbmi->bmiHeader.biCompression = BI_RGB ; pbmi->bmiHeader.biSizeImage = 0 ; pbmi->bmiHeader.biXPelsPerMeter = 0 ; pbmi->bmiHeader.biYPelsPerMeter = 0 ; pbmi->bmiHeader.biClrUsed = cColors ; pbmi->bmiHeader.biClrImportant = 0 ; hDib = DibCreateFromInfo (pbmi) ; free (pbmi) ; return hDib ; } /*---------------------------------------------------------------------------- DibCopyToInfo: Builds BITMAPINFO structure. Used by DibCopy and DibCopyToDdb -----------------------------------------------------------------------------*/ static BITMAPINFO * DibCopyToInfo (HDIB hdib) { BITMAPINFO * pbmi ; int i, iNumColors ; RGBQUAD * prgb ; if (!DibIsValid (hdib)) return NULL ; // Allocate the memory if (NULL == (pbmi = malloc (DibInfoSize (hdib)))) return NULL ; // Copy the information header CopyMemory (pbmi, DibInfoHeaderPtr (hdib), sizeof (BITMAPINFOHEADER)); // Copy the possible color masks prgb = (RGBQUAD *) ((BYTE *) pbmi + sizeof (BITMAPINFOHEADER)) ; if (DibMaskSize (hdib)) { CopyMemory (prgb, DibMaskPtr (hdib), 3 * sizeof (DWORD)) ; prgb = (RGBQUAD *) ((BYTE *) prgb + 3 * sizeof (DWORD)) ; } // Copy the color table iNumColors = DibNumColors (hdib) ; for (i = 0 ; i < iNumColors ; i++) DibGetColor (hdib, i, prgb + i) ; return pbmi ; } /*-------------------------------------------------------------------------- DibCopy: Creates a new DIB section from an existing DIB section, possibly swapping the DIB width and height. ---------------------------------------------------------------------------*/ 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 ( hdibDst == NULL) return NULL ; // Copy the bits if (!fRotate) { pBitsSrc = DibBitsPtr (hdibSrc) ; pBitsDst = DibBitsPtr (hdibDst) ; CopyMemory (pBitsDst, pBitsSrc, DibBitsSize (hdibSrc)) ; } return hdibDst ; } /*---------------------------------------------------------------------------- DibCopyToPackedDib is generally used for saving DIBs and for transferring DIBs to the clipboard. In the second case, the second argument should be set to TRUE so that the memory is allocated with the GMEM_SHARE flag. -----------------------------------------------------------------------------*/ BITMAPINFO * DibCopyToPackedDib (HDIB hdib, BOOL fUseGlobal) { BITMAPINFO * pPackedDib ; BYTE * pBits ; DWORD dwDibSize ; HDC hdcMem ; HGLOBAL hGlobal ; int iNumColors ; PDIBSTRUCT pdib = hdib ; RGBQUAD * prgb ; if (!DibIsValid (hdib)) return NULL ; // Allocate memory for packed DIB dwDibSize = DibTotalSize (hdib) ; if (fUseGlobal) { hGlobal = GlobalAlloc (GHND | GMEM_SHARE, dwDibSize) ; pPackedDib = GlobalLock (hGlobal) ; } else { pPackedDib = malloc (dwDibSize) ; } if (pPackedDib == NULL) return NULL ; // Copy the information header CopyMemory (pPackedDib, &pdib->ds.dsBmih, sizeof (BITMAPINFOHEADER)) ; prgb = (RGBQUAD *) ((BYTE *) pPackedDib + sizeof (BITMAPINFOHEADER)) ; // Copy the possible color masks if (pdib->ds.dsBmih.biCompression == BI_BITFIELDS) { CopyMemory (prgb, pdib->ds.dsBitfields, 3 * sizeof (DWORD)) ; prgb = (RGBQUAD *) ((BYTE *) prgb + 3 * sizeof (DWORD)) ; } // Copy the color table if (iNumColors = DibNumColors (hdib)) { hdcMem = CreateCompatibleDC (NULL) ; SelectObject (hdcMem, pdib->hBitmap) ; GetDIBColorTable (hdcMem, 0, iNumColors, prgb) ; DeleteDC (hdcMem) ; } pBits = (BYTE *) (prgb + iNumColors) ; // Copy the bits CopyMemory (pBits, pdib->pBits, DibBitsSize (pdib)) ; // If last argument is TRUE, unlock global memory block and // cast it to pointer in preparation for return if (fUseGlobal) { GlobalUnlock (hGlobal) ; pPackedDib = (BITMAPINFO *) hGlobal ; } return pPackedDib ; } /*-------------------------------------------------------------------------- DibCopyFromPackedDib is generally used for pasting DIBs from the clipboard. ------------------------------------------------------------------------*/ HDIB DibCopyFromPackedDib (BITMAPINFO * pPackedDib) { BYTE * pBits ; DWORD dwInfoSize, dwMaskSize, dwColorSize ; int iBitCount ; PDIBSTRUCT pdib ; // Get the size of the information header and do validity check dwInfoSize = pPackedDib->bmiHeader.biSize ; if ( dwInfoSize != sizeof (BITMAPCOREHEADER) && dwInfoSize != sizeof (BITMAPINFOHEADER) && dwInfoSize != sizeof (BITMAPV4HEADER) && dwInfoSize != sizeof (BITMAPV5HEADER)) { return NULL ; } // Get the possible size of the color masks if (dwInfoSize == sizeof (BITMAPINFOHEADER) && pPackedDib->bmiHeader.biCompression == BI_BITFIELDS) { dwMaskSize = 3 * sizeof (DWORD) ; } else { dwMaskSize = 0 ; } // Get the size of the color table if (dwInfoSize == sizeof (BITMAPCOREHEADER)) { iBitCount = ((BITMAPCOREHEADER *) pPackedDib)->bcBitCount ; if (iBitCount <= 8) { dwColorSize = (1 << iBitCount) * sizeof (RGBTRIPLE) ; } else dwColorSize = 0 ; } else // all non-OS/2 compatible DIBs { if (pPackedDib->bmiHeader.biClrUsed > 0) { dwColorSize = pPackedDib->bmiHeader.biClrUsed * sizeof (RGBQUAD); } else if (pPackedDib->bmiHeader.biBitCount <= 8) { dwColorSize = (1 << pPackedDib->bmiHeader.biBitCount) * sizeof (RGBQUAD) ; } else { dwColorSize = 0 ; } } // Finally, get the pointer to the bits in the packed DIB pBits = (BYTE *) pPackedDib + dwInfoSize + dwMaskSize + dwColorSize ; // Create the HDIB from the packed-DIB pointer pdib = DibCreateFromInfo (pPackedDib) ; // Copy the pixel bits CopyMemory (pdib->pBits, pBits, DibBitsSize (pdib)) ; return pdib ; } /*---------------------------------------------------------------------------- DibFileLoad: Creates a DIB section from a DIB file -----------------------------------------------------------------------------*/ HDIB DibFileLoad (const TCHAR * szFileName) { BITMAPFILEHEADER bmfh ; BITMAPINFO * pbmi ; BOOL bSuccess ; DWORD dwInfoSize, dwBitsSize, dwBytesRead ; HANDLE hFile ; HDIB hDib ; // Open the file: read access, prohibit write access hFile = CreateFile (szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL) ; if (hFile == INVALID_HANDLE_VALUE) return NULL ; // Read in the BITMAPFILEHEADER bSuccess = ReadFile ( hFile, &bmfh, sizeof (BITMAPFILEHEADER), &dwBytesRead, NULL) ; if (!bSuccess || (dwBytesRead != sizeof (BITMAPFILEHEADER)) || (bmfh.bfType != * (WORD *) "BM")) { CloseHandle (hFile) ; return NULL ; } // Allocate memory for the information structure & read it in dwInfoSize = bmfh.bfOffBits - sizeof (BITMAPFILEHEADER) ; if (NULL == (pbmi = malloc (dwInfoSize))) { CloseHandle (hFile) ; return NULL ; } bSuccess = ReadFile (hFile, pbmi, dwInfoSize, &dwBytesRead, NULL) ; if (!bSuccess || (dwBytesRead != dwInfoSize)) { CloseHandle (hFile) ; free (pbmi) ; return NULL ; } // Create the DIB hDib = DibCreateFromInfo (pbmi) ; free (pbmi) ; if (hDib == NULL) { CloseHandle (hFile) ; return NULL ; } // Read in the bits 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: Saves a DIB section to a file ----------------------------------------------------------------------------*/ BOOL DibFileSave (HDIB hdib, const TCHAR * szFileName) { BITMAPFILEHEADER bmfh ; BITMAPINFO * pbmi ; BOOL bSuccess ; DWORD dwTotalSize, dwBytesWritten ; HANDLE hFile ; hFile = CreateFile (szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) ; if (hFile == INVALID_HANDLE_VALUE) return FALSE ; dwTotalSize = DibTotalSize (hdib) ; bmfh.bfType = * (WORD *) "BM" ; bmfh.bfSize = sizeof (BITMAPFILEHEADER) + dwTotalSize ; bmfh.bfReserved1 = 0 ; bmfh.bfReserved2 = 0 ; bmfh.bfOffBits = bmfh.bfSize - DibBitsSize (hdib) ; // Write the BITMAPFILEHEADER bSuccess = WriteFile ( hFile, &bmfh, sizeof (BITMAPFILEHEADER), &dwBytesWritten, NULL) ; if (!bSuccess || (dwBytesWritten != sizeof (BITMAPFILEHEADER))) { CloseHandle (hFile) ; DeleteFile (szFileName) ; return FALSE ; } // Get entire DIB in packed-DIB format if (NULL == (pbmi = DibCopyToPackedDib (hdib, FALSE))) { CloseHandle (hFile) ; DeleteFile (szFileName) ; return FALSE ; } // Write out the packed DIB bSuccess = WriteFile (hFile, pbmi, dwTotalSize, &dwBytesWritten, NULL) ; CloseHandle (hFile) ; free (pbmi) ; if (!bSuccess || (dwBytesWritten != dwTotalSize)) { DeleteFile (szFileName) ; return FALSE ; } return TRUE ; } /*--------------------------------------------------------------------------- DibCopyToDdb: For more efficient screen displays ---------------------------------------------------------------------------*/ HBITMAP DibCopyToDdb (HDIB hdib, HWND hwnd, HPALETTE hPalette) { BITMAPINFO * pbmi ; HBITMAP hBitmap ; 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 ; }
�ⲿ�ֵ�DIBHELP.C����������С��ʽ��ʼ����������ʽ����16λԪ��32λԪDIB����ɫ���ֵõ�������λֵ����Щ��ʽ�ڵ�ʮ���¡���ɫ���֡�һ��˵����
DibCreateFromInfo��ʽ��DIBHELP��Ψһ����CreateDIBSection��ΪDIBSTRUCT�ṹ���ü�����ĺ�ʽ���������н����͸��ƺ�ʽ���ظ��˺�ʽ��DibCreateFromInfoΨһ�IJ�����ָ��BITMAPINFO�ṹ��ָ�ꡣ�˽ṹ����ɫ��������ڣ���������������Ч��ֵ��䡣����CreateDIBSection֮�ᣬ�ú�ʽ����ʼ��DIBSTRUCT�ṹ��������λ��ע�⣬���趨DIBSTRUCT�ṹ��ppRow��λ��ֵʱ��ָ��DIB��λַ��ָ�꣩��DIB�����¶��Ϻ����϶��µIJ�ͬ���淽ʽ��ppRow��ͷ��Ԫ�ؾ���DIB�Ķ��С�
DibDeleteɾ��DibCreateFromInfo�н����ĵ���ͼ��ͬʱ�ͷ��ڸú�ʽ�����õļ����塣
DibCreate���ܱ�DibCreateFromInfo����һ����Ӧ�ó�ʽ���еĺ�ʽ��ǰ���������ṩͼ�صĿ��ȡ��߶Ⱥ�ÿͼ�ص�λ��������һ�����������趨Ϊ0�������ɫ�����ڶ��ߴ磩�������趨Ϊ��0����ʾ��ÿͼ��λԪ������Ҫ����ɫ����С����ɫ������
DibCopy��ʽ�����ִ��DIB���齨���µ�DIB���飬����DibCreateInfo��ʽΪBITMAPINFO�ṹ�����˼����壬���������е����ϡ�DibCopy��ʽ��һ��BOOL����ָ���Ƿ��ڽ����µ�DIBʱ������DIB�Ŀ��Ⱥ͸߶ȡ����ǽ������濴���˺�ʽ���÷���
DibCopyToPackedDib��DibCopyFromPackedDib��ʽ��ʹ��ͨ����͸������������DIB��ء�DibFileLoad��ʽ��DIB��������DIB���飻DibFileSave��ʽ�����ϴ��浽DIB������
���ᣬDibCopyToDdb��ʽ����DIB����GDI����ͼ�����ע�⣬�ú�ʽ��ҪĿǰ��ɫ�̵Ĵ��źͳ�ʽ�Ӵ��Ĵ��š���ʽ�Ӵ�������춻��ѡ�������ֵ�ɫ�̵�װ�����ݡ�ֻ����������ʽ�ſ��Ժ���CreateDIBitmap�������ڱ���ǰ���SHOWDIB7��չʾ��
DIBHELP��ͷ�����;޼�
��
DIBHELP.H��ͷ�������ʽ16-22��ʾ��
��ʽ16-22 DIBHELP.H���� DIBHELP.H /*-------------------------------------------------------------------------- DIBHELP.H header file for DIBHELP.C ----------------------------------------------------------------------------*/ typedef void * HDIB ; // Functions in DIBHELP.C BOOL DibIsValid (HDIB hdib) ; HBITMAP DibBitmapHandle (HDIB hdib) ; int DibWidth (HDIB hdib) ; int DibHeight (HDIB hdib) ; int DibBitCount (HDIB hdib) ; int DibRowLength (HDIB hdib) ; 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) ; BOOL DibIsAddressable (HDIB hdib) ; 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 fUseGlobal) ; 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) ; /*--------------------------------------------------------------------------- Quickie no-bounds-checked pixel gets and 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) &= ~( 1 << (7 - ((x) & 7)))), \ (* DibPixelPtr1 (hdib, x, y) |= ((p) << (7 - ((x) & 7))))) #define DibSetPixel4(hdib, x, y, p) \ ((* DibPixelPtr4 (hdib, x, y) &= (0x0F << ((x) & 1 ? 4 : 0))), \ (* DibPixelPtr4 (hdib, x, y) |= ((p) << ((x) & 1 ? 0 : 4)))) #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)
�����ͷ������HDIB����Ϊ��ָ��(void* )��Ӧ�ó�ʽ��ȷ����Ҫ�˽�HDIB��ָ�ṹ���ڲ��ṹ���˱�ͷ����������DIBHELP.C�����к�ʽ��˵��������һЩ�޼����dz�����ľ޼���
����ٿ�һ��DIBHELP.C�е�DibPixelPtr��DibGetPixel��DibSetPixel��ʽ������ͼ������ǵ�ִ���ٶȱ��֣���ô�����������ֿ��ܵĽ����������һ�֣�����ɾ�����еļ�鱣����������Ӧ�ó�ʽ����ʹ����Ч�������к�ʽ��������ɾ��һЩ��ʽ���У�����DibBitCount����ʹ��ָ��DIBSTRUCT�ṹ�ڲ���ָ����ֱ�ӻ����Ѷ��
���ִ���ٶȱ�����һ��ϲ����Եķ�����ɾ�����ж�ÿͼ��λԪ���Ĵ�����ʽ��ͬʱ�����������ͬDIB��ʽ������DibGetPixel1��DibGetPixel4��DibGetPixel8�ȵȡ���һ����ѻ�������ɾ��������ʽ���У����䴦������͸��inline function��޼��н��кϲ���
DIBHELP.H���þ޼��ķ�����������DibPixelPtr��DibGetPixel��DibSetPixel��ʽ��������׾޼�����Щ�޼�����ȷ��Ӧ������ͼ��λԪ����
DIBBLE��ʽ
��
DIBBLE��ʽ�����ʽ16-23��ʾ��ʹ��DIBHELP��ʽ�;޼�����������DIBBLE�DZ�������ij�ʽ����ȷʵֻ��һЩ��ҵ�Ĵ��Է�������Щ��ҵ�����ڼ򵥵���λӰ������ʽ���ҵ�����DIBBLE�����ԸĽ���ת�����˶����ļ����棨MDI��multiple document interface�������ǽ��ڵ�ʮ����ѧϰ�йض����ļ������֪ʶ��
��ʽ16-23 DIBBLE DIBBLE.C /*--------------------------------------------------------------------------- DIBBLE.C -- Bitmap and Palette Program (c) Charles Petzold, 1998 -----------------------------------------------------------------------------*/ #include <windows.h> #include "dibhelp.h" #include "dibpal.h" #include "dibconv.h" #include "resource.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) ; TCHAR szAppName[] = TEXT ("Dibble") ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HACCEL hAccel ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = szAppName ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox ( NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow ( szAppName, szAppName, WS_OVERLAPPEDWINDOW | WM_VSCROLL | WM_HSCROLL, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; hAccel = LoadAccelerators (hInstance, szAppName) ; while (GetMessage (&msg, NULL, 0, 0)) { if (!TranslateAccelerator (hwnd, hAccel, &msg)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } } return msg.wParam ; } /*---------------------------------------------------------------------------- DisplayDib: Displays or prints DIB actual size or stretched depending on menu selection -----------------------------------------------------------------------------*/ 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, 0, 0, min (cxClient, cxBitmap - x), min (cyClient, cyBitmap - y), hdcMem, x, y, min (cxClient, cxBitmap - x), min (cyClient, cyBitmap - y), SRCCOPY); else iReturn = BitBlt (hdc,0, 0, min (cxClient, cxBitmap - x), min (cyClient, cyBitmap - y), hdcMem, x, y, SRCCOPY) ; break ; case IDM_SHOW_CENTER: if (fHalftonePalette) iReturn = StretchBlt ( hdc, (cxClient - cxBitmap) / 2, (cyClient - cyBitmap) / 2, cxBitmap, cyBitmap, hdcMem, 0, 0, cxBitmap, cyBitmap, SRCCOPY); else iReturn = BitBlt (hdc, (cxClient - cxBitmap) / 2, cyClient - cyBitmap) / 2, cxBitmap, cyBitmap, hdcMem, 0, 0, SRCCOPY) ; break ; case IDM_SHOW_STRETCH: iReturn = StretchBlt (hdc, 0, 0, cxClient, cyClient, hdcMem, 0, 0, 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 / 2, cyBitmap / 2, NULL) ; SetViewportOrgEx (hdc, cxClient / 2, cyClient / 2, NULL) ; iReturn = StretchBlt (hdc, 0, 0, cxBitmap, cyBitmap, hdcMem, 0, 0, cxBitmap, cyBitmap, SRCCOPY) ; break ; } DeleteDC (hdcMem) ; RestoreDC (hdc, -1) ; return iReturn ; } /*--------------------------------------------------------------------------- DibFlipHorizontal: Calls non-optimized DibSetPixel and 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 = 0 ; x < cx ; x++) for (y = 0 ; y < cy ; y++) { DibSetPixel (hdibDst, x, cy - 1 - y, DibGetPixel (hdibSrc, x, y)) ; } return hdibDst ; } /*--------------------------------------------------------------------------- DibRotateRight: Calls optimized DibSetPixelx and 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 1: for ( x = 0 ; x < cx ; x++) for ( y = 0 ; y < cy ; y++) DibSetPixel1 (hdibDst, cy - y - 1, x, DibGetPixel1 (hdibSrc, x, y)) ; break ; case 4: for ( x = 0 ; x < cx ; x++) for ( y = 0 ; y < cy ; y++) DibSetPixel4 (hdibDst, cy - y - 1, x, DibGetPixel4 (hdibSrc, x, y)) ; break ; case 8: for ( x = 0 ; x < cx ; x++) for ( y = 0 ; y < cy ; y++) DibSetPixel8 (hdibDst, cy - y - 1, x, DibGetPixel8 (hdibSrc, x, y)) ; break ; case 16: for (x = 0 ; x < cx ; x++) for (y = 0 ; y < cy ; y++) DibSetPixel16 (hdibDst, cy - y - 1, x, DibGetPixel16 (hdibSrc, x, y)) ; break ; case 24: for (x = 0 ; x < cx ; x++) for (y = 0 ; y < cy ; y++) DibSetPixel24 (hdibDst, cy - y - 1, x, DibGetPixel24 (hdibSrc, x, y)) ; break ; case 32: for (x = 0 ; x < cx ; x++) for (y = 0 ; y < cy ; y++) DibSetPixel32 (hdibDst, cy - y - 1, x, DibGetPixel32 (hdibSrc, x, y)) ; break ; } return hdibDst ; } /*------------------------------------------------------------------------ PaletteMenu: Uncheck and check menu item on palette menu --------------------------------------------------------------------------*/ 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 BOOL fHalftonePalette ; static DOCINFO di = {sizeof(DOCINFO),TEXT("Dibble:Printing")} ; static HBITMAP hBitmap ; static HDIB hdib ; static HMENU hMenu ; static HPALETTE hPalette ; static int cxClient, cyClient, iVscroll, iHscroll ; static OPENFILENAME ofn ; static PRINTDLG printdlg = { sizeof (PRINTDLG) } ; 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 WORD wShow = IDM_SHOW_NORMAL ; BOOL fSuccess ; BYTE * pGlobal ; HDC hdc, hdcPrn ; HGLOBAL hGlobal ; HDIB hdibNew ; int iEnable, cxPage, cyPage, iConvert ; PAINTSTRUCT ps ; SCROLLINFO si ; TCHAR szBuffer [256] ; switch (message) { case WM_CREATE: // Save the menu handle in a static variable hMenu = GetMenu (hwnd) ; // Initialize the OPENFILENAME structure for the File Open // and File Save dialog boxes. ofn.lStructSize = sizeof (OPENFILENAME) ; ofn.hwndOwner = hwnd ; ofn.hInstance = NULL ; ofn.lpstrFilter = szFilter ; ofn.lpstrCustomFilter = NULL ; ofn.nMaxCustFilter = 0 ; ofn.nFilterIndex = 0 ; ofn.lpstrFile = szFileName ; ofn.nMaxFile = MAX_PATH ; ofn.lpstrFileTitle = szTitleName ; ofn.nMaxFileTitle = MAX_PATH ; ofn.lpstrInitialDir = NULL ; ofn.lpstrTitle = NULL ; ofn.Flags = OFN_OVERWRITEPROMPT ; ofn.nFileOffset = 0 ; ofn.nFileExtension = 0 ; ofn.lpstrDefExt = TEXT ("bmp") ; ofn.lCustData = 0 ; ofn.lpfnHook = NULL ; ofn.lpTemplateName = NULL ; return 0 ; case WM_DISPLAYCHANGE: SendMessage (hwnd, WM_USER_DELETEPAL, 0, 0) ; SendMessage (hwnd, WM_USER_CREATEPAL, TRUE, 0) ; return 0 ; case WM_SIZE: // Save the client area width and height in static variables. cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; wParam = FALSE ; // fall through // WM_USER_SETSCROLLS: Programmer-defined Message! // Set the scroll bars. If the display mode is not normal, // make them invisible. If wParam is TRUE, reset the // scroll bar position. case WM_USER_SETSCROLLS: if (hdib == NULL || wShow != IDM_SHOW_NORMAL) { si.cbSize = sizeof (SCROLLINFO) ; si.fMask = SIF_RANGE ; si.nMin = 0 ; si.nMax = 0 ; SetScrollInfo (hwnd, SB_VERT, &si, TRUE) ; SetScrollInfo (hwnd, SB_HORZ, &si, TRUE) ; } else { // First the vertical scroll si.cbSize = sizeof (SCROLLINFO) ; si.fMask = SIF_ALL ; GetScrollInfo (hwnd, SB_VERT, &si) ; si.nMin = 0 ; si.nMax = DibHeight (hdib) ; si.nPage = cyClient ; if ((BOOL) wParam) si.nPos = 0 ; SetScrollInfo (hwnd, SB_VERT, &si, TRUE) ; GetScrollInfo (hwnd, SB_VERT, &si) ; iVscroll = si.nPos ; // Then the horizontal scroll GetScrollInfo (hwnd, SB_HORZ, &si) ; si.nMin = 0 ; si.nMax = DibWidth (hdib) ; si.nPage = cxClient ; if ((BOOL) wParam) si.nPos = 0 ; SetScrollInfo (hwnd, SB_HORZ, &si, TRUE) ; GetScrollInfo (hwnd, SB_HORZ, &si) ; iHscroll = si.nPos ; } return 0 ; // WM_VSCROLL: Vertically scroll the DIB 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 - = 1 ; break ; case SB_LINEDOWN: si.nPos + = 1 ; break ; case SB_PAGEUP: si.nPos - = si.nPage ;break ; case SB_PAGEDOWN: si.nPos + = 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, 0, iVscroll - si.nPos, NULL, NULL) ; iVscroll = si.nPos ; UpdateWindow (hwnd) ; } return 0 ; // WM_HSCROLL: Horizontally scroll the DIB 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 -=1 ; break ; case SB_LINERIGHT: si.nPos +=1 ; break ; case SB_PAGELEFT: si.nPos -=si.nPage ;break ; case SB_PAGERIGHT: si.nPos +=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, 0, NULL, NULL) ; iHscroll = si.nPos ; UpdateWindow (hwnd) ; } return 0 ; // WM_INITMENUPOPUP: Enable or Gray menu items 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 1: EnableMenuItem (hMenu, IDM_CONVERT_01, MF_GRAYED) ; break ; case 4: EnableMenuItem (hMenu, IDM_CONVERT_04, MF_GRAYED) ; break ; case 8: EnableMenuItem (hMenu, IDM_CONVERT_08, MF_GRAYED) ; break ; case 16: EnableMenuItem (hMenu, IDM_CONVERT_16, MF_GRAYED) ; break ; case 24: EnableMenuItem (hMenu, IDM_CONVERT_24, MF_GRAYED) ; break ; case 32: EnableMenuItem (hMenu, IDM_CONVERT_32, MF_GRAYED) ; break ; } if (hdib && DibColorSize (hdib) > 0) iEnable = MF_ENABLED ; else iEnable = MF_GRAYED ; EnableMenuItem (hMenu, IDM_PAL_DIBTABLE, iEnable) ; if (DibIsAddressable (hdib) && DibBitCount (hdib) > 8) 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 0 ; // WM_COMMAND: Process all menu commands. case WM_COMMAND: iConvert = 0 ; switch (LOWORD (wParam)) { case IDM_FILE_OPEN: // Show the File Open dialog box if (!GetOpenFileName (&ofn)) return 0 ; // If there's an existing DIB and palette, delete them SendMessage (hwnd, WM_USER_DELETEDIB, 0, 0) ; // Load the DIB into memory SetCursor (LoadCursor (NULL, IDC_WAIT)) ; ShowCursor (TRUE) ; hdib = DibFileLoad (szFileName) ; ShowCursor (FALSE) ; SetCursor (LoadCursor (NULL, IDC_ARROW)) ; // Reset the scroll bars SendMessage (hwnd, WM_USER_SETSCROLLS, TRUE, 0) ; // Create the palette and DDB SendMessage (hwnd, WM_USER_CREATEPAL, TRUE, 0) ; if (!hdib) { MessageBox (hwnd, TEXT ("Cannot load DIB file!"), szAppName, MB_OK | MB_ICONEXCLAMATION) ; } InvalidateRect (hwnd, NULL, TRUE) ; return 0 ; case IDM_FILE_SAVE: // Show the File Save dialog box if (! GetSaveFileName (&ofn)) return 0 ; // Save the DIB to memory SetCursor (LoadCursor (NULL, IDC_WAIT)) ; ShowCursor (TRUE) ; fSuccess = DibFileSave (hdib, szFileName) ; ShowCursor (FALSE) ; SetCursor (LoadCursor (NULL, IDC_ARROW)) ; if (!fSuccess) MessageBox ( hwnd, TEXT ("Cannot save DIB file!"), szAppName, MB_OK | MB_ICONEXCLAMATION) ; return 0 ; case IDM_FILE_PRINT: if (!hdib) return 0 ; // Get printer DC printdlg.Flags = PD_RETURNDC | PD_NOPAGENUMS | PD_NOSELECTION ; if (!PrintDlg (&printdlg)) return 0 ; if (NULL == (hdcPrn = printdlg.hDC)) { MessageBox( hwnd, TEXT ("Cannot obtain Printer DC"), szAppName, MB_ICONEXCLAMATION | MB_OK) ; return 0 ; } // Check if the printer can print bitmaps if (!(RC_BITBLT & GetDeviceCaps (hdcPrn, RASTERCAPS))) { DeleteDC (hdcPrn) ; MessageBox ( hwnd, TEXT ("Printer cannot print bitmaps"), szAppName, MB_ICONEXCLAMATION | MB_OK) ; return 0 ; } // Get size of printable area of page cxPage = GetDeviceCaps (hdcPrn, HORZRES) ; cyPage = GetDeviceCaps (hdcPrn, VERTRES) ; fSuccess = FALSE ; // Send the DIB to the printer SetCursor (LoadCursor (NULL, IDC_WAIT)) ; ShowCursor (TRUE) ; if ((StartDoc (hdcPrn, &di) > 0) && (StartPage (hdcPrn) > 0)) { DisplayDib (hdcPrn, DibBitmapHandle (hdib), 0, 0, cxPage, cyPage, wShow, FALSE) ; if (EndPage (hdcPrn) > 0) { fSuccess = TRUE ; EndDoc (hdcPrn) ; } } ShowCursor (FALSE) ; SetCursor (LoadCursor (NULL, IDC_ARROW)) ; DeleteDC (hdcPrn) ; if ( !fSuccess) MessageBox ( hwnd, TEXT ("Could not print bitmap"), szAppName, MB_ICONEXCLAMATION | MB_OK) ; return 0 ; case IDM_FILE_PROPERTIES: if (!hdib) return 0 ; wsprintf (szBuffer, TEXT ("Pixel width:\t%i\n") 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 (3, DibCompression (hdib))]) ; MessageBox ( hwnd, szBuffer, szAppName, MB_ICONEXCLAMATION | MB_OK) ; return 0 ; case IDM_APP_EXIT: SendMessage (hwnd, WM_CLOSE, 0, 0) ; return 0 ; case IDM_EDIT_COPY: case IDM_EDIT_CUT: if (!(hGlobal = DibCopyToPackedDib (hdib, TRUE))) return 0 ; OpenClipboard (hwnd) ; EmptyClipboard () ; SetClipboardData (CF_DIB, hGlobal) ; CloseClipboard () ; if (LOWORD (wParam) == IDM_EDIT_COPY) return 0 ; // fall through for IDM_EDIT_CUT case IDM_EDIT_DELETE: SendMessage (hwnd, WM_USER_DELETEDIB, 0, 0) ; InvalidateRect (hwnd, NULL, TRUE) ; return 0 ; case IDM_EDIT_PASTE: OpenClipboard (hwnd) ; hGlobal = GetClipboardData (CF_DIB) ; pGlobal = GlobalLock (hGlobal) ; // If there's an existing DIB and palette,delete them. // Then convert the packed DIB to an HDIB. if (pGlobal) { SendMessage (hwnd, WM_USER_DELETEDIB, 0, 0) ; hdib = DibCopyFromPackedDib ((BITMAPINFO *) pGlobal) ; SendMessage (hwnd, WM_USER_CREATEPAL, TRUE, 0) ; } GlobalUnlock (hGlobal) ; CloseClipboard () ; // Reset the scroll bars SendMessage (hwnd, WM_USER_SETSCROLLS, TRUE, 0) ; InvalidateRect (hwnd, NULL, TRUE) ; return 0 ; 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, 0) ; InvalidateRect (hwnd, NULL, TRUE) ; } else { MessageBox ( hwnd, TEXT ("Not enough memory"), szAppName, MB_OK | MB_ICONEXCLAMATION) ; } return 0 ; 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 0 ; case IDM_SHOW_NORMAL: case IDM_SHOW_CENTER: case IDM_SHOW_STRETCH: case IDM_SHOW_ISOSTRETCH: CheckMenuItem (hMenu, wShow, MF_UNCHECKED) ; wShow = LOWORD (wParam) ; CheckMenuItem (hMenu, wShow, MF_CHECKED) ; SendMessage (hwnd, WM_USER_SETSCROLLS, FALSE, 0) ; InvalidateRect (hwnd, NULL, TRUE) ; return 0 ; case IDM_CONVERT_32: iConvert += 8 ; case IDM_CONVERT_24: iConvert += 8 ; case IDM_CONVERT_16: iConvert += 8 ; case IDM_CONVERT_08: iConvert += 4 ; case IDM_CONVERT_04: iConvert += 3 ; case IDM_CONVERT_01: iConvert += 1 ; 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, 0, 0) ; hdib = hdibNew ; SendMessage (hwnd, WM_USER_CREATEPAL, TRUE, 0) ; InvalidateRect (hwnd, NULL, TRUE) ; } else { MessageBox ( hwnd, TEXT ("Not enough memory"), szAppName, MB_OK | MB_ICONEXCLAMATION) ; } return 0 ; case IDM_APP_ABOUT: MessageBox ( hwnd, TEXT ("Dibble (c) Charles Petzold, 1998"), szAppName, MB_OK | MB_ICONEXCLAMATION) ; return 0 ; } // All the other WM_COMMAND messages are from the palette // items. Any existing palette is deleted, and the cursor // is set to the hourglass. SendMessage (hwnd, WM_USER_DELETEPAL, 0, 0) ; SetCursor (LoadCursor (NULL, IDC_WAIT)) ; ShowCursor (TRUE) ; // Notice that all messages for palette items are ended // with break rather than return. This is to allow // additional processing later on. 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 (2) ; break; case IDM_PAL_GRAY3:hPalette = DibPalUniformGrays (3) ; break; case IDM_PAL_GRAY4:hPalette = DibPalUniformGrays (4) ; break; case IDM_PAL_GRAY8:hPalette = DibPalUniformGrays (8) ; break; case IDM_PAL_GRAY16:hPalette = DibPalUniformGrays (16) ; break; case IDM_PAL_GRAY32:hPalette = DibPalUniformGrays (32) ; break; case IDM_PAL_GRAY64:hPalette = DibPalUniformGrays (64) ; break; case IDM_PAL_GRAY128:hPalette = DibPalUniformGrays (128) ; break; case IDM_PAL_GRAY256:hPalette = DibPalUniformGrays (256) ; break; case IDM_PAL_RGB222:hPalette = DibPalUniformColors (2,2,2); break; case IDM_PAL_RGB333:hPalette = DibPalUniformColors (3,3,3); break; case IDM_PAL_RGB444:hPalette = DibPalUniformColors (4,4,4); break; case IDM_PAL_RGB555:hPalette = DibPalUniformColors (5,5,5); break; case IDM_PAL_RGB666:hPalette = DibPalUniformColors (6,6,6); break; case IDM_PAL_RGB775:hPalette = DibPalUniformColors (7,7,5); break; case IDM_PAL_RGB757:hPalette = DibPalUniformColors (7,5,7); break; case IDM_PAL_RGB577:hPalette = DibPalUniformColors (5,7,7); break; case IDM_PAL_RGB884:hPalette = DibPalUniformColors (8,8,4); break; case IDM_PAL_RGB848:hPalette = DibPalUniformColors (8,4,8); break; case IDM_PAL_RGB488:hPalette = DibPalUniformColors (4,8,8); break; case IDM_PAL_OPT_POP4:hPalette = DibPalPopularity (hdib, 4) ; break ; case IDM_PAL_OPT_POP5:hPalette = DibPalPopularity (hdib, 5) ; break ; case IDM_PAL_OPT_POP6:hPalette = DibPalPopularity (hdib, 6) ; break ; case IDM_PAL_OPT_MEDCUT:hPalette = DibPalMedianCut (hdib, 6) ; break ; } // After processing Palette items from the menu, the cursor // is restored to an arrow, the menu item is checked, and // the window is invalidated. hBitmap = DibCopyToDdb (hdib, hwnd, hPalette) ; ShowCursor (FALSE) ; SetCursor (LoadCursor (NULL, IDC_ARROW)) ; if (hPalette) PaletteMenu (hMenu, (LOWORD (wParam))) ; InvalidateRect (hwnd, NULL, TRUE) ; return 0 ; // This programmer-defined message deletes an existing DIB // in preparation for getting a new one. Invoked during // File Open command, Edit Paste command, and others. case WM_USER_DELETEDIB: if (hdib) { DibDelete (hdib) ; hdib = NULL ; } SendMessage (hwnd, WM_USER_DELETEPAL, 0, 0) ; return 0 ; // This programmer-defined message deletes an existing palette // in preparation for defining a new one. case WM_USER_DELETEPAL: if (hPalette) { DeleteObject (hPalette) ; hPalette = NULL ; fHalftonePalette = FALSE ; PaletteMenu (hMenu, IDM_PAL_NONE) ; } if (hBitmap) DeleteObject (hBitmap) ; return 0 ; // Programmer-defined message to create a new palette based on // a new DIB. If wParam == TRUE, create a DDB as well. case WM_USER_CREATEPAL: if (hdib) { hdc = GetDC (hwnd) ; if (!(RC_PALETTE & GetDeviceCaps (hdc, RASTERCAPS))) { PaletteMenu (hMenu, IDM_PAL_NONE) ; } else if (hPalette = DibPalDibTable (hdib)) { PaletteMenu (hMenu, IDM_PAL_DIBTABLE) ; } else if (hPalette = CreateHalftonePalette (hdc)) { fHalftonePalette = TRUE ; PaletteMenu (hMenu, IDM_PAL_HALFTONE) ; } ReleaseDC (hwnd, hdc) ; if ((BOOL) wParam) hBitmap = DibCopyToDdb (hdib, hwnd, hPalette) ; } return 0 ; 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 0 ; 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) break ; 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 (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
DIBBLE.RC ��ժ¼�� //Microsoft Developer Studio generated resource script. #include "resource.h" #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// // Menu DIBBLE MENU DISCARDABLE 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 x 2G x 2B (8)", IDM_PAL_RGB222 MENUITEM "&2. 3R x 3G x 3B (27)", IDM_PAL_RGB333 MENUITEM "&3. 4R x 4G x 4B (64)", IDM_PAL_RGB444 MENUITEM "&4. 5R x 5G x 5B (125)", IDM_PAL_RGB555 MENUITEM "&5. 6R x 6G x 6B (216)", IDM_PAL_RGB666 MENUITEM "&6. 7R x 7G x 5B (245)", IDM_PAL_RGB775 MENUITEM "&7. 7R x 5B x 7B (245)", IDM_PAL_RGB757 MENUITEM "&8. 5R x 7G x 7B (245)", IDM_PAL_RGB577 MENUITEM "&9. 8R x 8G x 4B (256)", IDM_PAL_RGB884 MENUITEM "&A. 8R x 4G x 8B (256)", IDM_PAL_RGB848 MENUITEM "&B. 4R x 8G x 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 ", 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 bits per pixel", IDM_CONVERT_08 MENUITEM "&4. to 16 bits per pixel", IDM_CONVERT_16 MENUITEM "&5. to 24 bits 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 DISCARDABLE BEGIN "C", IDM_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT "O", IDM_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT "P", IDM_FILE_PRINT, VIRTKEY, CONTROL, NOINVERT "S", IDM_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT "V", IDM_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT VK_DELETE, IDM_EDIT_DELETE, VIRTKEY, NOINVERT "X", IDM_EDIT_CUT, VIRTKEY, CONTROL, NOINVERT END
RESOURCE.H ��ժ¼�� // Microsoft Developer Studio generated include file. // Used by 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_PAL_OPT_POP4 40040 #define IDM_PAL_OPT_POP5 40041 #define IDM_PAL_OPT_POP6 40042 #define IDM_PAL_OPT_MEDCUT 40043 #define IDM_CONVERT_01 40044 #define IDM_CONVERT_04 40045 #define IDM_CONVERT_08 40046 #define IDM_CONVERT_16 40047 #define IDM_CONVERT_24 40048 #define IDM_CONVERT_32 40049 #define IDM_APP_ABOUT 40050
DIBBLEʹ�������������������ҽ���Ҫ��˵�����ǡ�DIBCONV������DIBCONV.C��DIBCONV.H�������ֲ�ͬ��ʽ֮��ת�������磬��ÿͼ��24λԪת����ÿͼ��8λԪ��DIBPAL������DIBPAL.C��DIBPAL.H��������ɫ�̡�
DIBBLEά��WndProc�е�������Ҫ�ľ�̬��������Щ�Ǻ���hdib��HDIB���š�����hPalette��HPALETTE���źͺ���hBitmap��HBITMAP���š�HDIB����DIBHELP�еIJ�ͬ��ʽ��HPALETTE����DIBPAL�еIJ�ͬ��ʽ��CreateHalftonePalette��ʽ����HBITMAP��������DIBHELP.C�е�DibCopyToDdb��ʽ����������өĻ��ʾ���ر�����256ɫ��ʾģʽ�¡������������ڳ�ʽ�����µġ�DIB Section�����Զ��׼��أ����ڳ�ʽ������ͬ�ĵ�ɫ�̣��������ԣ�ʱ��������Ŷ��������½�����
�����Ǵӹ����϶���Ñ�ò½¥½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ò»ï¿½ï¿½DIBBLE��
��������ʹ���
��
DIBBLE�����ڻ�ӦIDM_FILE_LOAD��IDM_FILE_SAVE��WM_COMMANDѶϢ��������������DIB������������Щ�������ڴ�����ЩѶϢ�����ڼ䣬DIBBLEͨ���ֱ����GetOpenFileName��GetSaveFileName���������õ����Ի����顣
��춡�File������Save�����ܱ����DIBBLEֻ��Ҫ����DibFileSave����춡�File������Open�����ܱ����DIBBLE��������ɾ��ǰ���HDIB����ɫ�̺͵���ͼ�������͸������һ��WM_USER_DELETEDIBѶϢ���������£���ѶϢͨ������DibDelete��DeleteObject��������Ȼ��DIBBLE����DIBHELP�е�DibFileLoad��ʽ������WM_USER_SETSCROLLS��WM_USER_CREATEPALѶϢ�������趨�����в�������ɫ�̡�WM_USER_CREATEPALѶϢҲλ춳�ʽ��DIB���齨�����µ�DDBλ�á�
��ʾ����������ӡ
��
DIBBLE�Ĺ��ܱ���������ʵ�ʳߴ�����ʾ�������Ͻ���ʾDIB��������ʾ�����м���ʾDIB������չ�������ʾ���򣬻����ڱ����ݺ�ȵ�����¾��������ʾ������������DIBBLE�ġ�Show�����ܱ�����ѡ����Ҫ��ѡ�ע�⣬��Щ����һ�µ�SHOWDIB2��ʽ���ĸ�ѡ����ͬ��
��WM_PAINTѶϢ�����ڼä£Ò²ï¿½Ç´ï¿½ï¿½ï¿½ï¿½ï¿½File������Print������Ĺ����У�DIBBLE����DisplayDib��ʽ��ע�⣬DisplayDibʹ��BitBlt��StretchBlt��������ʹ��SetDIBitsToDevice��StretchDIBits����WM_PAINTѶϢ�����ڼ䣬���ݸ���ʽ�ĵ���ͼ������DibCopyToDdb��ʽ����������WM_USER_CREATEPALѶϢ�����ڼ���С�����DDB����Ѷװ���������ݡ���������File������Print������ʱ��DIBBLE����DisplayDib�����п��õ�DIB�����������DIBHELP.C�е�DibBitmapHandle��ʽ��
����Ҫע�⣬DIBBLE����һ������fHalftonePalette�ľ�̬BOOL�����������CreateHalftonePalette��ʽ�л��hPalette����˱����趨ΪTRUE���⽫��ʹDisplayDib��ʽ����StretchBlt�����Ǻ���BitBlt����ʹDIB��ָ����ʵ�ʳߴ���ʾ��fHalftonePalette����Ҳ����WM_PAINT������ʽ��DIB������Ŵ��ݸ�DisplayDib��ʽ����������DibCopyToDdb��ʽ�����ĵ���ͼ���š�����ǰ�����۹��м�ɫ��ɫ�̵�ʹ�ã�����SHOWDIB5��ʽ�н�����չʾ��
��һ��ʹ�÷�����ʽʱ��DIBBLE��������ʾ�����о���DIB��ֻ�а�ʵ�ʳߴ���ʾDIBʱ������ʾ�����С��ڴ���WM_PAINTʱ��WndProc�򵥵ؽ������е�Ŀǰλ�ô��ݸ�DisplayDib��ʽ��
������
��
��춡�Cut���͡�Copy�����ܱ��DIBBLE����DIBHELP�е�DibCopyToPackedDib��ʽ���ú�ʽ��������е�DIBԪ���������Ƿ����ļ�������С�
��춵�һ��ʹ�ñ����е�ijЩ������ʽ��˵��DIBBLE�Ӽ�������ճ��DIB�����������DibCopyFromPackedDib��ʽ�����滻�Ӵ�ѶϢ������ʽǰ�洢���HDIB����ɫ�̺͵���ͼ��
��ת����ת
��
DIBBLE�еġ�Edit�����ܱ��г��˳����ġ�Cut������Copy������Paste���͡�Delete��ѡ��֮�⣬���������������î£ï¿½ï¿½Flip���͡�Rotate������Flip��ѡ��ʹ����ͼ��ˮƽ�á·×ªï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Âµßµï¿½ï¿½ï¿½×ªï¿½ï¿½ï¿½ï¿½Rotate��ѡ��ʹ����ͼ˳ʱ����ת90�ȡ���������ʽ����Ҫ͸�������Ǵ�һ��DIB���Ƶ���һ������ȡ���е�DIBͼ�أ���Ϊ��������ʽ����Ҫ�����µĵ�ɫ�̣����Բ�ɾ�������½�����ɫ�̣���
��Flip�����ܱ�ѡ��ʹ��DibFlipHorizontal��ʽ���˺�ʽҲλ�DIBBLE.C�������˺�ʽ����DibCopy�����DIB��ȷ�ĸ�����Ȼ�ᣬ���뽫ÔDIB�е�ͼ�ظ��Ƶ���DIB�Ļ�Ȧ�����Ǹ�����Щͼ����Ϊ�����·�תͼ��ע�⣬�˺�ʽ����DibGetPixel��DibSetPixel������DIBHELP.C�е�ͨ�ã�������������ϣ������ô�죩��ʽ��
Ϊ��˵��DibGetPixel��DibSetPixel��ʽ��DIBHELP.H��ִ�и����DibGetPixel��DibSetPixel�޼�֮�������DibRotateRight��ʽʹ���˾޼���Ȼ��������Ҫע����ǣ��ú�ʽ����DibCopyʱ���ڶ��������趨ΪTRUE���⵼��DibCopy��תÔDIB�Ŀ��Ⱥ͸߶��������µ�DIB�����⣬ͼ��λԪ������DibCopy��ʽ���ơ����ǣ�DibRotateRight��ʽ��������ͬ�Ļ�Ȧ��ͼ��λԪ��ÔDIB���Ƶ��µ�DIB��ÿһ������Ӧ��ͬ��DIBͼ�ؿ��ȣ�1λԪ��4λԪ��8λԪ��16λԪ��24λԪ��32λԪ������Ȼ�����˸���ij�ʽ�룬���Ǻ�ʽ�����ˡ�
���ܿ���ʹ�á�Flip Horizontal���͡�Rotate Right��ѡ����������Flip Vertical������Rotate Left���͡�Rotate 180�㡹���ܣ���ͨ����ʽ��ֱ��ִ������ѡ��Ͼ���DIBBLEֻ�Ǹ�չʾ��ʽ���ѡ�
�򵥵�ɫ�̣���ѻ���ɫ��
��
��DIBBLE�У���������256ɫ��Ѷ��ʾ����ѡ��ͬ�ĵ�ɫ������ʾDIB����Щ����DIBBLE�ġ�Palette�����ܱ����г��������м�ɫ��ɫ�����⣬����Ķ�ֱ����Windows��ʽ���н�����������ͬ��ɫ�̵����к�ʽ���ɳ�ʽ16-24��ʾ��DIBPAL�����ṩ��
��ʽ16-24 DIBPAL���� DIBPAL.H /*-------------------------------------------------------------------------- DIBPAL.H header file for DIBPAL.C ----------------------------------------------------------------------------*/ HPALETTE DibPalDibTable (HDIB hdib) ; HPALETTE DibPalAllPurpose (void) ; HPALETTE DibPalUniformGrays (int iNum) ; HPALETTE DibPalUniformColors (int iNumR, int iNumG, int iNumB) ; HPALETTE DibPalVga (void) ; HPALETTE DibPalPopularity (HDIB hdib, int iRes) ; HPALETTE DibPalMedianCut (HDIB hdib, int iRes) ;
DIBPAL.C /*---------------------------------------------------------------------------- DIBPAL.C -- Palette-Creation Functions (c) Charles Petzold, 1998 -------------------------------------------------------------------------*/ #include <windows.h> #include "dibhelp.h" #include "dibpal.h" /*--------------------------------------------------------------------------- DibPalDibTable: Creates a palette from the DIB color table -----------------------------------------------------------------------------*/ HPALETTE DibPalDibTable (HDIB hdib) { HPALETTE hPalette ; int i, iNum ; LOGPALETTE * plp ; RGBQUAD rgb ; if (0 == (iNum = DibNumColors (hdib))) return NULL ; plp = malloc (sizeof (LOGPALETTE) + (iNum - 1) * sizeof (PALETTEENTRY)) ; plp->palVersion = 0x0300 ; plp->palNumEntries = iNum ; for (i = 0 ; i < iNum ; i++) { DibGetColor (hdib, i, &rgb) ; plp->palPalEntry[i].peRed = rgb.rgbRed ; plp->palPalEntry[i].peGreen = rgb.rgbGreen ; plp->palPalEntry[i].peBlue = rgb.rgbBlue ; plp->palPalEntry[i].peFlags = 0 ; } hPalette = CreatePalette (plp) ; free (plp) ; return hPalette ; } /*--------------------------------------------------------------------------- DibPalA llPurpose: Creates a palette suitable for a wide variety of images; the palette has 247 entries, but 15 of them are duplicates or match the standard 20 colors. ----------------------------------------------------------------------------*/ HPALETTE DibPalAllPurpose (void) { HPALETTE hPalette ; int i, incr, R, G, B ; LOGPALETTE * plp ; plp = malloc (sizeof (LOGPALETTE) + 246 * sizeof (PALETTEENTRY)) ; plp->palVersion = 0x0300 ; plp->palNumEntries = 247 ; // The following loop calculates 31 gray shades, but 3 of them // will match the standard 20 colors for (i = 0, G = 0, incr = 8 ; G <= 0xFF ; i++, G += incr) { plp->palPalEntry[i].peRed = (BYTE) G ; plp->palPalEntry[i].peGreen = (BYTE) G ; plp->palPalEntry[i].peBlue = (BYTE) G ; plp->palPalEntry[i].peFlags = 0 ; incr = (incr == 9 ? 8 : 9) ; } // The following loop is responsible for 216 entries, but 8 of // them will match the standard 20 colors, and another // 4 of them will match the gray shades above. for (R = 0 ; R <= 0xFF ; R += 0x33) for (G = 0 ; G <= 0xFF ; G += 0x33) for (B = 0 ; B <= 0xFF ; B += 0x33) { plp->palPalEntry[i].peRed = (BYTE) R ; plp->palPalEntry[i].peGreen = (BYTE) G ; plp->palPalEntry[i].peBlue = (BYTE) B ; plp->palPalEntry[i].peFlags = 0 ; i++ ; } hPalette = CreatePalette (plp) ; free (plp) ; return hPalette ; } /*--------------------------------------------------------------------------- DibPalUniformGrays: Creates a palette of iNum grays, uniformly spaced ----------------------------------------------------------------------------*/ HPALETTE DibPalUniformGrays (int iNum) { HPALETTE hPalette ; int i ; LOGPALETTE * plp ; plp = malloc (sizeof (LOGPALETTE) + (iNum - 1) * sizeof (PALETTEENTRY)) ; plp->palVersion = 0x0300 ; plp->palNumEntries = iNum ; for (i = 0 ; i < iNum ; i++) { plp->palPalEntry[i].peRed = plp->palPalEntry[i].peGreen = plp->palPalEntry[i].peBlue = (BYTE) (i * 255 / (iNum - 1)) ; plp->palPalEntry[i].peFlags = 0 ; } hPalette = CreatePalette (plp) ; free (plp) ; return hPalette ; } /*-------------------------------------------------------------------------- DibPalUniformColors: Creates a palette of iNumR x iNumG x iNumB colors ----------------------------------------------------------------------------*/ HPALETTE DibPalUniformColors (int iNumR, int iNumG, int iNumB) { HPALETTE hPalette ; int i, iNum, R, G, B ; LOGPALETTE * plp ; iNum = iNumR * iNumG * iNumB ; plp = malloc (sizeof (LOGPALETTE) + (iNum - 1) * sizeof (PALETTEENTRY)) ; plp->palVersion = 0x0300 ; plp->palNumEntries = iNumR * iNumG * iNumB ; i = 0 ; for (R = 0 ; R < iNumR ; R++) for (G = 0 ; G < iNumG ; G++) for (B = 0 ; B < iNumB ; B++) { plp->palPalEntry[i].peRed = (BYTE) (R * 255 / (iNumR - 1)) ; plp->palPalEntry[i].peGreen = (BYTE) (G * 255 / (iNumG - 1)) ; plp->palPalEntry[i].peBlue = (BYTE) (B * 255 / (iNumB - 1)) ; plp->palPalEntry[i].peFlags = 0 ; i++ ; } hPalette = CreatePalette (plp) ; free (plp) ; return hPalette ; } /*--------------------------------------------------------------------------- DibPalVga: Creates a palette based on standard 16 VGA colors ----------------------------------------------------------------------------*/ HPALETTE DibPalVga (void) { static RGBQUAD rgb [16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00 } ; HPALETTE hPalette ; int i ; LOGPALETTE * plp ; plp = malloc (sizeof (LOGPALETTE) + 15 * sizeof (PALETTEENTRY)) ; plp->palVersion = 0x0300 ; plp->palNumEntries = 16 ; for (i = 0 ; i < 16 ; i++) { plp->palPalEntry[i].peRed = rgb[i].rgbRed ; plp->palPalEntry[i].peGreen = rgb[i].rgbGreen ; plp->palPalEntry[i].peBlue = rgb[i].rgbBlue ; plp->palPalEntry[i].peFlags = 0 ; } hPalette = CreatePalette (plp) ; free (plp) ; return hPalette ; } /*--------------------------------------------------------------------------- Macro used in palette optimization routines -------------------------------------------------------------------------*/ #define PACK_RGB(R,G,B,iRes) ((int) (R) | ((int) (G) << (iRes)) | \ ((int) (B) << ((iRes) + (iRes)))) /*---------------------------------------------------------------------------- AccumColorCounts: Fills up piCount (indexed by a packed RGB color) with counts of pixels of that color. -----------------------------------------------------------------------------*/ static void AccumColorCounts (HDIB hdib, int * piCount, int iRes) { int x, y, cx, cy ; RGBQUAD rgb ; cx = DibWidth (hdib) ; cy = DibHeight (hdib) ; for (y = 0 ; y < cy ; y++) for (x = 0 ; x < cx ; x++) { DibGetPixelColor (hdib, x, y, &rgb) ; rgb.rgbRed >>= (8 - iRes) ; rgb.rgbGreen >>= (8 - iRes) ; rgb.rgbBlue >>= (8 - iRes) ; ++piCount [PACK_RGB (rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue, iRes)] ; } } /*--------------------------------------------------------------------------- DibPalPopularity: Popularity algorithm for optimized colors -----------------------------------------------------------------------------*/ HPALETTE DibPalPopularity (HDIB hdib, int iRes) { HPALETTE hPalette ; int i, iArraySize, iEntry, iCount, iIndex, iMask, R, G, B ; int * piCount ; LOGPALETTE * plp ; // Validity checks if (DibBitCount (hdib) < 16) return NULL ; if (iRes < 3 || iRes > 8) return NULL ; // Allocate array for counting pixel colors iArraySize = 1 << (3 * iRes) ; iMask = (1 << iRes) - 1 ; if (NULL == (piCount = calloc (iArraySize, sizeof (int)))) return NULL ; // Get the color counts AccumColorCounts (hdib, piCount, iRes) ; // Set up a palette plp = malloc (sizeof (LOGPALETTE) + 235 * sizeof (PALETTEENTRY)) ; plp->palVersion = 0x0300 ; for (iEntry = 0 ; iEntry < 236 ; iEntry++) { for (i = 0, iCount = 0 ; i < iArraySize ; i++) if (piCount[i] > iCount) { iCount = piCount[i] ; iIndex = i ; } if (iCount == 0) break ; R = (iMask & iIndex) << (8 - iRes) ; G = (iMask & (iIndex >> iRes )) << (8 - iRes) ; B = (iMask & (iIndex >> (iRes + iRes)))<< (8 - iRes) ; plp->palPalEntry[iEntry].peRed = (BYTE) R ; plp->palPalEntry[iEntry].peGreen = (BYTE) G ; plp->palPalEntry[iEntry].peBlue = (BYTE) B ; plp->palPalEntry[iEntry].peFlags = 0 ; piCount [iIndex] = 0 ; } // On exit from the loop iEntry will be the number of stored entries plp->palNumEntries = iEntry ; // Create the palette, clean up, and return the palette handle hPalette = CreatePalette (plp) ; free (piCount) ; free (plp) ; return hPalette ; } /*-------------------------------------------------------------------------- Structures used for implementing median cut algorithm ----------------------------------------------------------------------------*/ typedef struct // defines dimension of a box { int Rmin, Rmax, Gmin, Gmax, Bmin, Bmax ; } MINMAX ; typedef struct // for Compare routine for qsort { int iBoxCount ; RGBQUAD rgbBoxAv ; } BOXES ; /*---------------------------------------------------------------------------- FindAverageColor: In a box -----------------------------------------------------------------------------*/ static int FindAverageColor ( int * piCount, MINMAX mm, int iRes, RGBQUAD * prgb) { int R, G, B, iR, iG, iB, iTotal, iCount ; // Initialize some variables iTotal = iR = iG = iB = 0 ; // Loop through all colors in the box for (R = mm.Rmin ; R <= mm.Rmax ; R++) for (G = mm.Gmin ; G <= mm.Gmax ; G++) for (B = mm.Bmin ; B <= mm.Bmax ; B++) { // Get the number of pixels of that color iCount = piCount [PACK_RGB (R, G, B, iRes)] ; // Weight the pixel count by the color value iR += iCount * R ; iG += iCount * G ; iB += iCount * B ; iTotal += iCount ; } // Find the average color prgb->rgbRed = (BYTE) ((iR / iTotal) << (8 - iRes)) ; prgb->rgbGreen = (BYTE) ((iG / iTotal) << (8 - iRes)) ; prgb->rgbBlue = (BYTE) ((iB / iTotal) << (8 - iRes)) ; // Return the total number of pixels in the box return iTotal ; } /*--------------------------------------------------------------------------- CutBox: Divide a box in two ----------------------------------------------------------------------------*/ static void CutBox (int * piCount, int iBoxCount, MINMAX mm, int iRes, int iLevel, BOXES * pboxes, int * piEntry) { int iCount, R, G, B ; MINMAX mmNew ; // If the box is empty, return if (iBoxCount == 0) return ; // If the nesting level is 8, or the box is one pixel, we're ready // to find the average color in the box and save it along with // the number of pixels of that color if (iLevel == 8 || ( mm.Rmin == mm.Rmax && mm.Gmin == mm.Gmax && mm.Bmin == mm.Bmax)) { pboxes[*piEntry].iBoxCount = FindAverageColor (piCount, mm, iRes, &pboxes[*piEntry].rgbBoxAv) ; (*piEntry) ++ ; } // Otherwise, if blue is the largest side, split it else if ((mm.Bmax - mm.Bmin > mm.Rmax - mm.Rmin) && (mm.Bmax - mm.Bmin > mm.Gmax - mm.Gmin)) { // Initialize a counter and loop through the blue side iCount = 0 ; for (B = mm.Bmin ; B < mm.Bmax ; B++) { // Accumulate all the pixels for each successive blue value for ( R = mm.Rmin ; R <= mm.Rmax ; R++) for ( G = mm.Gmin ; G <= mm.Gmax ; G++) iCount += piCount [PACK_RGB (R, G, B, iRes)] ; // If it's more than half the box count, we're there if (i Count >= iBoxCount / 2) break ; // If the next blue value will be the max, we're there if ( B == mm.Bmax - 1) break ; } // Cut the two split boxes. // The second argument to CutBox is the new box count. // The third argument is the new min and max values. mmNew = mm ; mmNew.Bmin = mm.Bmin ; mmNew.Bmax = B ; CutBox ( piCount, iCount, mmNew, iRes, iLevel + 1, pboxes, piEntry) ; mmNew.Bmin = B + 1 ; mmNew.Bmax = mm.Bmax ; CutBox ( piCount, iBoxCount - iCount, mmNew, iRes, iLevel + 1, pboxes, piEntry) ; } // Otherwise, if red is the largest side, split it (just like blue) else if (mm.Rmax - mm.Rmin > mm.Gmax - mm.Gmin) { iCount = 0 ; for (R = mm.Rmin ; R < mm.Rmax ; R++) { for (B = mm.Bmin ; B <= mm.Bmax ; B++) for (G = mm.Gmin ; G <= mm.Gmax ; G++) iCount += piCount [PACK_RGB (R, G, B, iRes)] ; if (iCount >= iBoxCount / 2) break ; if (R == mm.Rmax - 1) break ; } mmNew = mm ; mmNew.Rmin = mm.Rmin ; mmNew.Rmax = R ; CutBox ( piCount, iCount, mmNew, iRes, iLevel + 1, pboxes, piEntry) ; mmNew.Rmin = R + 1 ; mmNew.Rmax = mm.Rmax ; CutBox ( piCount, iBoxCount - iCount, mmNew, iRes, iLevel + 1, pboxes, piEntry) ; } // Otherwise, split along the green size else { iCount = 0 ; for (G = mm.Gmin ; G < mm.Gmax ; G++) { for ( B = mm.Bmin ; B <= mm.Bmax ; B++) for ( R = mm.Rmin ; R <= mm.Rmax ; R++) iCount += piCount [PACK_RGB (R, G, B, iRes)] ; if ( iCount >= iBoxCount / 2) break ; if ( G == mm.Gmax - 1) break ; } mmNew = mm ; mmNew.Gmin = mm.Gmin ; mmNew.Gmax = G ; CutBox ( piCount, iCount, mmNew, iRes, iLevel + 1, pboxes, piEntry) ; mmNew.Gmin = G + 1 ; mmNew.Gmax = mm.Gmax ; CutBox ( piCount, iBoxCount - iCount, mmNew, iRes, iLevel + 1, pboxes, piEntry) ; } } /*--------------------------------------------------------------------------- Compare routine for qsort -----------------------------------------------------------------------------*/ static int Compare (const BOXES * pbox1, const BOXES * pbox2) { return pbox1->iBoxCount - pbox2->iBoxCount ; } /*--------------------------------------------------------------------------- DibPalMedianCut: Creates palette based on median cut algorithm -------------------------------------------------------------------------*/ HPALETTE DibPalMedianCut (HDIB hdib, int iRes) { BOXES boxes [256] ; HPALETTE hPalette ; int i, iArraySize, iCount, R, G, B, iTotCount, iDim, iEntry = 0 ; int * piCount ; LOGPALETTE * plp ; MINMAX mm ; // Validity checks if (DibBitCount (hdib) < 16) return NULL ; if (iRes < 3 || iRes > 8) return NULL ; // Accumulate counts of pixel colors iArraySize = 1 << (3 * iRes) ; if (NULL == (piCount = calloc (iArraySize, sizeof (int)))) return NULL ; AccumColorCounts (hdib, piCount, iRes) ; // Find the dimensions of the total box iDim = 1 << iRes ; mm.Rmin = mm.Gmin = mm.Bmin = iDim - 1 ; mm.Rmax = mm.Gmax = mm.Bmax = 0 ; iTotCount = 0 ; for (R = 0 ; R < iDim ; R++) for (G = 0 ; G < iDim ; G++) for (B = 0 ; B < iDim ; B++) if ((iCount = piCount [PACK_RGB (R, G, B, iRes)]) > 0) { iTotCount += iCount ; if (R < mm.Rmin) mm.Rmin = R ; if (G < mm.Gmin) mm.Gmin = G ; if (B < mm.Bmin) mm.Bmin = B ; if (R > mm.Rmax) mm.Rmax = R ; if (G > mm.Gmax) mm.Gmax = G ; if (B > mm.Bmax) mm.Bmax = B ; } // Cut the first box (iterative function). // On return, the boxes structure will have up to 256 RGB values, // one for each of the boxes, and the number of pixels in // each box. // The iEntry value will indicate the number of non-empty boxes. CutBox (piCount, iTotCount, mm, iRes, 0, boxes, &iEntry) ; free (piCount) ; // Sort the RGB table by the number of pixels for each color qsort (boxes, iEntry, sizeof (BOXES), Compare) ; plp = malloc (sizeof (LOGPALETTE) + (iEntry - 1) * sizeof (PALETTEENTRY)) ; if (plp == NULL) return NULL ; plp->palVersion = 0x0300 ; plp->palNumEntries = iEntry ; for (i = 0 ; i < iEntry ; i++) { plp->palPalEntry[i].peRed = boxes[i].rgbBoxAv.rgbRed ; plp->palPalEntry[i].peGreen= boxes[i].rgbBoxAv.rgbGreen ; plp->palPalEntry[i].peBlue = boxes[i].rgbBoxAv.rgbBlue ; plp->palPalEntry[i].peFlags= 0 ; } hPalette = CreatePalette (plp) ; free (plp) ; return hPalette ; }
��һ����ʽ��DibPalDibTable��������Ӧ�ú���Ϥ��������DIB����ɫ�������˵�ɫ�̡����뱾��ǰ���SHOWDIB3�����õ���PACKEDIB.C���PackedDibCreatePalette��ʽ���ơ���SHOWDIB3�У�ֻ�е�DIB����ɫ��ʱ��ִ�д˺�ʽ����8λԪ��ʾģʽ����ͼ��ʾ16λԪ��24λԪ��32λԪDIBʱ���˺�ʽ��û���ˡ�
Ԥ������£�ִ����256ɫ��ʾģʽ��ʱ��DIBBLE�����ȳ��Ժ���DibPalDibTable������DIB��ɫ��������ɫ�̡����DIBû����ɫ������DIBBLE������CreateHalftonePalette����fHalftonePalette�����趨ΪTRUE�����߼�������WM_USER_CREATEPALѶϢ�����ڼ䡣
DIBPAL.CҲִ�к�ʽDibPalAllPurpose����Ϊ�˺�ʽ��SHOWDIB4�е�CreateAllPurposePalette��ʽ�dz����ƣ�������������Ҳ����Ϥ����Ҳ���Դ�DIBBLE���ܱ���ѡ��˵�ɫ�̡�
��256ɫģʽ����ʾ����ͼ����Ȥ���ǣ�������ֱ�ӿ���Windows�����ʾͼ�����ɫ�������ѡ�����ֵ�ɫ�̣���Winsows��ʹ�ô˵�ɫ���е���ɫ��������������ɫ���е���ɫ��
���磬��������DibPalUniformGrays��ʽ����������һ�ֻҽ׵�ɫ�̡�ʹ�����ֻҽ׵ĵ�ɫ����ֻ����00-00-00����ɫ����FF-FF-FF����ɫ�����ô˵�ɫ�������ͼ���ṩijЩ��Ƭ�г��õĸ߶Աȡ��ڰס�Ч����ʹ��3�ֻҽ׽��ں�ɫ�Ͱ�ɫ�м������м��ɫ��ʹ��4�ֻҽ׽�����2�ֻҽס�
��8�ֻҽף������п��ܿ������Ե���������ͬ�ҽ׵��޹���ߵ㣬��Ȼ�����Ե�ִ������ӽ���ɫ���㷨������һ���Բ������κ������жϡ�ͨ����16�ֻҽ׾Ϳ������Ը���ͼ���ʡ�ʹ��32�ֻҽײ��Ϳ�������ȫ�������ˡ���Ŀǰ�ձ���Ϊ64�ֻҽ������ڴ������ʾ�豸�ļ��ޡ���������ϣ�������Ҳûʲô�߼�Ч���ˡ���6λԪ��ɫ�����ȵ��豸���ṩ����64�ֻҽ׿�������ʲô�Ľ�֮����
����Ϊֹ�����8λԪ��ʾģʽ����ʾ16λԪ��24λԪ��32λԪ��ɫDIB�������������ܹ����ͨ�õ�ɫ�̣���Իҽ�ͼ�����Ч����ͨ������춲�ɫͼ�񣩻���ʹ���м�ɫ��ɫ�̣����û�ɫ��ʾ��ͨ����ɫ��ɫ�̺��á�
��Ӧע�⣬������8λԪ��ɫģʽ��Ϊ����16λԪ��24λԪ��32λԪDIBѡ��ͨ�õ�ɫ��ʱ��Ϊ��Ҫ��ʾ��Щͼ�񣬳�ʽ������һЩʱ������DIB������������GDI����ͼ������������Ҫ��ɫ�̣����ʽ����DIB������DDB��ʱ�����٣���8λԪ��ɫģʽ��ʾ��24λԪDIBʱ���Ƚ�SHOWDIB1��SHOWDIB4�����ܣ���Ҳ�ܿ���������𣩡�����Ϊʲô�أ�
������ӽ���ɫ��Ѱ��ͨ������8λԪ��ʾģʽ��ʾ24λԪDIBʱ�����߽�DIBת��ΪDDB����GDI���뽫DIB�е�ÿ��ͼ�ض��뾲̬20����ɫ�е�һ������������ɴ˲�����Ψһ�����Ǿ������־�̬��ɫ��ͼ����ɫ��ӽ������������ͼ������άRGB��ɫ��ÿ�־�̬��ɫ�ľ��롣�⽫��Щʱ�䣬�ر�����DIBͼ�������ϰ����ͼ��ʱ��
�ڽ���232ɫ��ɫ��ʱ������DIBBLE��SHOWDIB4�е�ͨ�õ�ɫ�̣�����ܿ콫������ӽ���ɫ��ʱ�����ӵ�����11����GDI���ڱ��볹�׼��232����ɫ��������20�֡��Ǿ�����ʾDIB��������ҵ������Ô��
����Ľ�ѵ�DZ�����8λԪ��ʾģʽ����ʾ24λԪ����16λԪ����32λԪ��DIB����Ӧ���ҳ���ӽ�DIBͼ����ɫ��Χ��256ɫ��ɫ�̣���������ת����8λԪDIB���â¾ï¿½ï¿½ï¿½ï¿½Îªï¿½ï¿½ï¿½ï¿½Ñµï¿½É«ï¿½Ì¡ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ð¾ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ê±ï¿½ï¿½Paul Heckbert��д�ġ�Color Image Quantization for Frame Buffer Displays����������1982��7�³���ġ�Computer Graphics�����Դ���������������
���ȷֲ�
��
����256ɫ��ɫ����òµ¥µÄ·ï¿½ï¿½ï¿½ï¿½ï¿½Ñ¡ï¿½ï¿½Î§Í³Ò»ï¿½ï¿½RGB��ɫֵ������DibPalAllPurpose�еķ������ơ��˷������ŵ��������ؼ��DIB�е�ʵ��ͼ�ء������ʽ��DibPalCreateUniformColors�������ݷ�Χͳһ��RGB��Ôɫ����������ɫ�̡�
һ�������ķֲ�����8�׺�ɫ����ɫ�Լ�4����ɫ�����۶���ɫ�ϲ����У�����ɫ����RGB��ɫֵ�ļ��ϣ����Ǻ�ɫ����ɫֵ0x00��0x24��0x49��0x6D��0x92��0xB6��0xDB��0xFF�Լ���ɫֵ0x00��0x55��0xAA��0xFF�����п��ܵ���ϣ�����256����ɫ����һ�ֿ��ܵ�ͳһ�ֲ���ɫ��ʹ��6�׺�ɫ����ɫ����ɫ���˵�ɫ���Ǻ�ɫ����ɫ����ɫֵΪ0x00��0x33��0x66��0x99��0xCC��0xFF�����п��ܵ���ϣ���ɫ���е���ɫ����6��3�η�����216��
������ѡ�����������ѡ���DIBBLE�ṩ��
��Popularity�����㷨
��
��Popularity�����㷨��256ɫ��ɫ�������൱���ԵĽ����������Ҫ���ľ����߱����ͼ�е�����ͼ�أ����ҳ�256������ͨ��RGB��ɫֵ����Щ�������ڵ�ɫ����ʹ�õ�ֵ��DIBPAL��DibPalPopularity��ʽ��ʵ�����������㷨��
���������ÿ����ɫ��ʹ������24λԪ�����Ҽ�����Ҫ���������������е���ɫ����ô���н�ռ��64MB�����塣���⣬�����Է��ֵ���ͼ��ʵ����û�У�����٣��ظ���24λԪͼ��ֵ��������û����ν��������ɫ�ˡ�
Ҫ���������⣬������ֻʹ��ÿ����ɫ����ɫ����ɫֵ������Ҫ��nλԪ�����磬6λԪ������8λԪ����Ϊ������IJ�ɫɨ��������Ѷ��ʾ����ֻ��6λԪ�Ľ����ȣ����������涨�������塣�⽫���м��ٵ���С��������256KB��1MB��ֻʹ��5λԪ�ܽ����õ���ɫ�������ٵ�32,768��ͨ����ʹ��5λԪҪ��6λԪ�����ܸ��á��Դˣ���������DIBBLE��һЩͼ����ɫ���Լ����顣
��Median Cut�����㷨
��
DIBPAL.C�е�DibPalMedianCut��ʽִ��Paul Heckbert��Median Cut���㷨�������㷨�ڸ������൱�򵥣����ڳ�ʽ����ʵ��Ҫ��Popularity���㷨�����ѣ����ʺϵݻغ�ʽ��
����RGB��ɫ�����塣ͼ���е�ÿ��ͼ�ض��Ǵ��������е�һ���㡣һЩ����ܴ���ͼ���еĶ��ͼ�ء��ҳ�����ͼ��������ͼ�ص����巽�飬�ҳ��˷�������ߴ磬��������ֳ�������ÿ�����鶼������ͬ������ͼ�ء�������������飬ִ����ͬ�IJ���������������4�����飬����4������ֳ�8����Ȼ���ٷֳ�16����32����64����128����256����
��������256�����飬ÿ�����鶼������ͬ������ͼ�ء�ȡÿ��������ͼ��RGB��ɫֵ��ƽ��ֵ�����������춵�ɫ�̡�
ʵ���ϣ���Щ����ͨ������ͼ�ص�����������ͬ�����磬ͨ������������ķ�����и����ͼ�ء��ⷢ���ں�ɫ�Ͱ�ɫ�ϡ���ʱ��һЩ������ͷ����û��ͼ�ء�������������Ϳ���ʡ�¸���ķ��飬�����Ҿ�������������
��һ����ѻ���ɫ�̵ļ�����Ϊ��octree quantization�����˼�����Jeff Prosise��������1996��8�·����ڡ�Microsoft Systems Journal���ϣ�������MSDN��CD�У���
ת����ʽ
��
DIBBLE��������DIB��һ�ָ�ʽת������һ�ָ�ʽ�����õ���DIBCONV�����е�DibConvert��ʽ�����ʽ16-25��ʾ��
��ʽ16-25 DIBCONV���� DIBCONV.H /*---------------------------------------------------------------------------- DIBCONV.H header file for DIBCONV.C -----------------------------------------------------------------------------*/ HDIB DibConvert (HDIB hdibSrc, int iBitCountDst) ;
DIBCONV.C /*--------------------------------------------------------------------------- DIBCONV.C -- Converts DIBs from one format to another (c) Charles Petzold, 1998 ----------------------------------------------------------------------------*/ #include <windows.h> #include "dibhelp.h" #include "dibpal.h" #include "dibconv.h" HDIB DibConvert (HDIB hdibSrc, int iBitCountDst) { HDIB hdibDst ; HPALETTE hPalette ; int i, x, y, cx, cy, iBitCountSrc, cColors ; PALETTEENTRY pe ; RGBQUAD rgb ; WORD wNumEntries ; cx = DibWidth (hdibSrc) ; cy = DibHeight (hdibSrc) ; iBitCountSrc = DibBitCount (hdibSrc) ; if (iBitCountSrc == iBitCountDst) return NULL ; // DIB with color table to DIB with larger color table: if ((iBitCountSrc < iBitCountDst) && (iBitCountDst <= 8)) { cColors = DibNumColors (hdibSrc) ; hdibDst = DibCreate (cx, cy, iBitCountDst, cColors) ; for (i = 0 ; i < cColors ; i++) { DibGetColor (hdibSrc, i, &rgb) ; DibSetColor (hdibDst, i, &rgb) ; } for (x = 0 ; x < cx ; x++) for (y = 0 ; y < cy ; y++) { DibSetPixel (hdibDst, x, y, DibGetPixel (hdibSrc, x, y)) ; } } // Any DIB to DIB with no color table else if (iBitCountDst >= 16) { hdibDst = DibCreate (cx, cy, iBitCountDst, 0) ; for (x = 0 ; x < cx ; x++) for (y = 0 ; y < cy ; y++) { DibGetPixelColor (hdibSrc, x, y, &rgb) ; DibSetPixelColor (hdibDst, x, y, &rgb) ; } } // DIB with no color table to 8-bit DIB else if (iBitCountSrc >= 16 && iBitCountDst == 8) { hPalette = DibPalMedianCut (hdibSrc, 6) ; GetObject (hPalette, sizeof (WORD), &wNumEntries) ; hdibDst = DibCreate (cx, cy, 8, wNumEntries) ; for (i = 0 ; i < (int) wNumEntries ; i++) { GetPaletteEntries (hPalette, i, 1, &pe) ; rgb.rgbRed = pe.peRed ; rgb.rgbGreen = pe.peGreen ; rgb.rgbBlue = pe.peBlue ; rgb.rgbReserved = 0 ; DibSetColor (hdibDst, i, &rgb) ; } for (x = 0 ; x < cx ; x++) for (y = 0 ; y < cy ; y++) { DibGetPixelColor (hdibSrc, x, y, &rgb) ; DibSetPixel (hdibDst, x, y, GetNearestPaletteIndex (hPalette, RGB (rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue))) ; } DeleteObject (hPalette) ; } // Any DIB to monochrome DIB else if (iBitCountDst == 1) { hdibDst = DibCreate (cx, cy, 1, 0) ; hPalette = DibPalUniformGrays (2) ; for (i = 0 ; i < 2 ; i++) { GetPaletteEntries (hPalette, i, 1, &pe) ; rgb.rgbRed = pe.peRed ; rgb.rgbGreen = pe.peGreen ; rgb.rgbBlue = pe.peBlue ; rgb.rgbReserved = 0 ; DibSetColor (hdibDst, i, &rgb) ; } for (x = 0 ; x < cx ; x++) for (y = 0 ; y < cy ; y++) { DibGetPixelColor (hdibSrc, x, y, &rgb) ; DibSetPixel (hdibDst, x, y, GetNearestPaletteIndex (hPalette, RGB (rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue))) ; } DeleteObject (hPalette) ; } // All non-monochrome DIBs to 4-bit DIB else if (iBitCountSrc >= 8 && iBitCountDst == 4) { hdibDst = DibCreate (cx, cy, 4, 0) ; hPalette = DibPalVga () ; for (i = 0 ; i < 16 ; i++) { GetPaletteEntries (hPalette, i, 1, &pe) ; rgb.rgbRed = pe.peRed ; rgb.rgbGreen = pe.peGreen ; rgb.rgbBlue = pe.peBlue ; rgb.rgbReserved = 0 ; DibSetColor (hdibDst, i, &rgb) ; } for (x = 0 ; x < cx ; x++) for (y = 0 ; y < cy ; y++) { DibGetPixelColor (hdibSrc, x, y, &rgb) ; DibSetPixel (hdibDst, x, y, GetNearestPaletteIndex (hPalette, RGB (rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue))) ; } DeleteObject (hPalette) ; } // Should not be necessary else hdibDst = NULL ; return hdibDst ; }
��DIB��һ�ָ�ʽת������һ�ָ�ʽ��Ҫ���ֲ�ͬ�ķ�����
Ҫ��������ɫ����DIBת������һ��Ҳ������ɫ�����нϴ��ͼ�ؿ��ȵ�DIB���༴����1λԪDIBת����4λԪ��8λԪDIB����4λԪDIBת����8λԪDIB��������Ҫ���ľ���͸������DibCreate�������µ�DIB�����ں���ʱ����ϣ����λԪ���Լ���ÔʼDIB�е���ɫ����ȵ���ɫ����Ȼ�ắʽ����ͼ��λԪ����ɫ����Ŀ��
����µ�DIBû����ɫ������λԪ����16��24��32������ôDIBֻ��Ҫ���¸�ʽ����������ͨ������DibGetPixelColor��DibSetPixelColor�����е�DIB�и���ͼ��λԪ��
�����������ܸ��ձ飺���е�DIBû����ɫ������λԪ����16��24��32�������µ�DIBÿͼ��ռ8λԪ����������£�DibConvert����DibPalMedianCut��Ϊͼ������ѻ��ĵ�ɫ�̡���DIB����ɫ���趨Ϊ��ɫ���е�RGBֵ��DibGetPixelColor��ʽ�����е�DIB�л��ͼ����ɫ��͸������GetNearestPaletteIndex��ת����8λԪDIB�е�ͼ��ֵ����͸������DibSetPixel��ͼ��ֵ���浽DIB��
��DIB��Ҫת���ɵ�ɫDIBʱ���ð���������Ŀ����ɫ�Ͱ�ɫ������ɫ�������µ�DIB�����⣬GetNearestPaletteIndex����춽�����DIB�е���ɫת����ͼ��ֵ0��1�����Ƶأ���8��ͼ��λԪ�����λԪ��DIBҪת����4λԪDIBʱ���ɴ�DibPalVga��ʽ���DIB��ɫ����ͬʱGetNearestPaletteIndexҲ����춼���ͼ��ֵ��
����DIBBLEʾ������ο�ʼдһ��ͼ������ʽ���������dz�ʽ���ỹ��û��ȫ����ɣ��������ǻ��뵽����Щ����û�мӽ�ȥ��ͷ�����Ǻܿ�ϧ���ǣ��������ڵ�ֹͣ�����о���Щ���������������۱�Ķ����ˡ�