�������� Linux Tags

15. ��װ���޹صĵ���ͼ

����һ�������˽⵽Windows GDI����ͼ�����Ҳ��Ϊ��װ����صĵ���ͼ����DDB���������ʽ�����;�������Ҳ�û��չʾ����Щ����ͼ���浽��Ƭ��������������������ķ�����������ǰ��Windows��ʹ�õķ��������ڸ��������ˡ���Ϊ����ͼ��λԪ��ʽ�൱������豸������DDB�������ͼ�񽻻���DDB��û��ɫ�ʶ��ձ���ָ������ͼ��λ��ɫ��֮�����ϵ��DDBֻ����Windows�������ػ����������ڱ����������ʱ�������塣

��Windows 3.0�з�������װ���޹صĵ���ͼ(DIB)���ṩ������춽�����ͼ�񵵰���ʽ����������֪�ģ���.GIF��.JPEG֮�������ͼ�񵵰���ʽ��Internet�ϱ�DIB����������������Ҫ����Ϊ.GIF��.JPEG��ʽ������ѹ�������Եؼ��������ص�ʱ�䡣������һ�����DIB��ѹ��������������ʹ�á�DIB�ڵĵ���ͼ������û�б�ѹ������������ڳ�ʽ�в�������ͼ����ʵ������һ���ŵ㡣DIB����.GIF��.JPEG������Windows APIֱ��֧ԮDIB������ڼ���������DIB�����Ϳ����ṩָ���DIB��ָ����ΪijЩ��ʽ�IJ���������ʾDIB���DIBת��ΪDDB��

DIB������ʽ
��

����˼���ǣ�DIB��ʽ������Դ���Windows�������ȶ�����OS/2��1.1���У�����ҵϵͳ�����IBM��Microsoft�ڰ�ʮ������ڿ�ʼ������OS/2 1.1��1988�귢���������ǵ�һ������������Windows��ͼ��ʹ���߽����OS/2�汾����ͼ��ʹ���߽��汻��֮Ϊ��Presentation Manager��PM��������Presentation Manager�������˶������ͼ��ʽ�ġ�ͼ�γ�ʽ���桹��GPI����

Ȼ����Windows 3.0�У������1990��ʹ����OS/2����ͼ��ʽ����ʱ��֮ΪDIB��Windows 3.0Ҳ������ԭʼDIB��ʽ�ı��壬����Windows�³�Ϊ��׼����Windows 95���Լ�Windows NT 4.0����Windows 98���Լ�Windows NT 5.0����Ҳ������һЩ��������ǿ�������һ��ڱ����������ǡ�

DIB������Ϊһ�ֵ�����ʽ�����ĸ�����Ϊ.BMP���ڼ��������Ϊ.DIB��WindowsӦ�ó�ʽʹ�õĵ���ͼͼ�񱻵���DIB��������������ΪΨ����Դ�����ڳ�ʽ�Ŀ�ִ�е����С�ͼʾ�ͻ����α�Ҳ����ʽ���в�ͬ��DIB������

��ʽ�ܽ�DIB������ȥǰ14��λԪ�����������ļ�������С���ʱ�Ϳ��Գ���Ϊ��packed DIB��packed-DIB����ʽ�ĵ���ͼ������Windows��ִ�е�Ӧ�ó�ʽ��ʹ��packed DIB��ʽ��ͨ��Windows������������ͼ�������ˢ����ʽҲ������ȫ��ȡDIB�����ݲ������ⷽʽ�޸�DIB��

��ʽҲ���ڼ������н����Լ���DIBȻ������Ǵ��뵵������ʽʹ��GDI��ʽ���о��ܡ����ơ���ЩDIB�ڵ�ͼ��Ҳ���ڳ��������ñ�ļ�����DIBֱ���趨�Ͳ���ͼ��λԪ��

�ڼ�������������DIB�ᣬ��ʽҲ��ͨ������Windows API��ʽ������ʹ��DIB���ϣ��ҽ��ڱ����������й����ݡ���DIB��ص�API�����Ǻ��ٵģ�������Ҫ����Ѷ��ʾ����ӡ����ҳ������ʾDIB��أ�����ת��GDI����ͼ����йء�

������Щ�������⣬��������Ӧ�ó�ʽ��Ҫ��ɵ�DIB���񣬶���Щ����Windows��ҵϵͳ����֧Ԯ�����磬��ʽ���ܴ�ȡ��24λԪDIB���������ת��Ϊ������ѻ���256ɫ��ɫ�̵�8λԪDIB����Windows����Ϊ��ִ����Щ�����������ڱ��º���һ�½�������ʾWindows API֮��IJ���DIB�ķ�ʽ��

OS/2��ʽ��DIB
��

�Ȳ�Ҫ����̫���ϸ�ڣ������ǿ�һ����������OS/2 1.1�г��ֵĵ���ͼ��ʽ���ݵ�Windows DIB��ʽ��

DIB�������ĸ���Ҫ���֣�

  • ������ͷ
    ��
  • ��Ѷ��ͷ
    ��
  • RGBɫ�ʶ��ձ�����һ���У�
    ��
  • ����ͼͼ��λԪ
    ��

�����԰�ǰ�����ֿ�����C�����Ͻṹ���ѵ������ֿ��������Ͻṹ�����С���Windows��ͷ����WINGDI.H��˵������Щ�ṹ���ڼ������е�packed DIB��ʽ�����������֣�

  • ��Ѷ��ͷ
    ��
  • RGBɫ�ʶ��ձ�����һ���У�
    ��
  • ����ͼͼ��λԪ
    ��

����û�е�����ͷ�⣬���������봢���ڵ����ڵ�DIB��ͬ��

DIB���������Ǽ������е�packed DIB���Զ���Ϊ���½ṹ��14��λԪ��ĵ�����ͷ��ʼ��

typedef struct tagBITMAPFILEHEADER  // bmfh
{ 
     	WORD  		bfType ;        // signature word "BM" or 0x4D42
     	DWORD 		bfSize ;        // entire size of file
     	WORD  		bfReserved1 ;   // must be zero
     	WORD  		bfReserved2 ;   // must be zero
     	DWORD 		bfOffsetBits ;  // offset in file of DIB pixel bits
}
BITMAPFILEHEADER, * PBITMAPFILEHEADER ;

��WINGDI.H�ڶ���Ľṹ�������ⲻ��ȫ��ͬ�����ڹ���������ͬ�ġ���һ��ע�ͣ��������֡�bmfh����ָ���˸�����������̬�����ϱ�������ʱ�Ƽ�����д��������ҵij�ʽ�ڿ�������Ϊpbmfh�ı������������һ��ָ��BITMAPFILEHEADER��̬�ṹ��ָ���ָ��PBITMAPFILEHEADER��̬������ָ�ꡣ

�ṹ�ij���Ϊ14λԪ�飬����������ĸ��BM����ͷ��ָ���ǵ���ͼ����������һ��WORDֵ0x4D42�������ڡ�BM�����DWORD��λԪ��Ϊ��λָ���˰���������ͷ���ڵĵ�����С��������WORD��λ�趨Ϊ0��������DIB������ʽ���ƵĻ����α굵���ڣ���������λָ���α�ġ��ȵ㣨hot spot���������ṹ������һ��DWORD��λ����ָ���˵�����ͼ��λԪ��ʼλ�õ�λԪ��ƫ����������ֵ����DIB��Ѷ��ͷ�е���Ѷ��Ϊ��ʹ�õķ����ṩ�����

��OS/2��ʽ��DIB�ڣ�BITMAPFILEHEADER�ṹ�������BITMAPCOREHEADER�ṹ�����ṩ�˹��DIBͼ��Ļ�����Ѷ��������DIB��Packed DIB����ʼ�BITMAPCOREHEADER��

typedef struct tagBITMAPCOREHEADER  // bmch
{ 
     	DWORD 		bcSize ;      		// size of the structure = 12
     	WORD  		bcWidth ;     		// width of image in pixels
     	WORD  		bcHeight ;    		// height of image in pixels
     	WORD  		bcPlanes ;    		// = 1
     	WORD  		bcBitCount ;  		// bits per pixel (1, 4, 8, or 24)
}
BITMAPCOREHEADER, * PBITMAPCOREHEADER ;

��core�����ģ����������￴�����е����أ�����ָ���ָ�ʽ�����������������ĵ���ͼ��ʽ�Ļ�����

BITMAPCOREHEADER�ṹ�е�bcSize��λָ�������Ͻṹ�Ĵ�С���������������12λԪ�顣

bcWidth��bcHeight��λ��������ͼ��Ϊ��λ�ĵ���ͼ��С��������Щ��λʹ��WORD��ζ��һ��DIB����Ϊ65,535ͼ�ظߺͿ����������Ǽ��������õ���ô��ĵ�λ��

bcPlanes��λ��ֵʼ����1�������λ����������һ��������������Windows GDI����ͼ����IJ����

bcBitCount��λָ����ÿͼ�ص�λԪ�������OS/2��ʽ��DIB���������1��4��8��24��DIBͼ���е���ɫ�����2bmch.bcBitCount������C���﷨��ʾΪ��

1 << bmch.bcBitCount

������bcBitCount��λ��춣�

  • 1����2É«DIB
    ��
  • 4����16É«DIB
    ��
  • 8����256É«DIB
    ��
  • 24����full -Color DIB
    ��

�����ᵽ��8λԪDIB��ʱ������˵ÿͼ��ռ8λԪ��DIB��

���ǰ���������Ҳ����λԪ��Ϊ1��4��8ʱ����BITMAPCOREHEADER�����ɫ�ʶ��ձ���24λԪDIBû��ɫ�ʶ��ձ���ɫ�ʶ��ձ���һ��3λԪ��RGBTRIPLE�ṹ�����У������е�ÿ��Ԫ�ش���ͼ���е�ÿ����ɫ��

typedef struct tagRGBTRIPLE  // rgbt
{
     	BYTE rgbtBlue ;   	// blue level
     	BYTE rgbtGreen ;  	// green level
     	BYTE rgbtRed ;    	// red level
}
RGBTRIPLE ;

��������ɫ�ʶ��ձ��Ա�DIB������Ҫ����ɫ������ʾ�����ǽ�����һ��˵��ԭ��

WINGDI.H��ͷ����Ҳ����������Ľṹ��

typedef struct tagBITMAPCOREINFO  // bmci
{
     	BITMAPCOREHEADER 	bmciHeader ;     		// core-header structure
     	RGBTRIPLE        	bmciColors[1] ;  		// color table array
}
BITMAPCOREINFO, * PBITMAPCOREINFO ;

����ṹ����Ѷ��ͷ��ɫ�ʶ��ձ������������Ȼ������ṹ��RGBTRIPLE�ṹ���������1������DIB�����������Բ��ᷢ��ֻ��һ��RGBTRIPLE������ÿ��ͼ�ص�λԪ����ɫ�ʶ��ձ��Ĵ�Сʼ����2��16��256��RGBTRIPLE�ṹ�������ҪΪ8λԪDIB����PBITMAPCOREINFO�ṹ����������������

pbmci = malloc (sizeof (BITMAPCOREINFO) + 255 * sizeof (RGBTRIPLE)) ;

Ȼ�����������ȡRGBTRIPLE�ṹ��

pbmci->bmciColors[i]

��ΪRGBTRIPLE�ṹ�ij�����3λԪ�飬����RGBTRIPLE�ṹ������DIB��������λַ��ʼ��Ȼ������Ϊ��DIB������ʼ����ż������RGBTRIPLE�ṹ�����Խ�����ɫ�ʶ��ձ�����������Ͽ�������WORDλַ�߽翪ʼ��

������ɫ�ʶ��ձ���24λԪDIB������Ѷ��ͷ�����������ͼ��λԪ������

���¶���
��

����������ͼ��ʽһ����DIB�е�ͼ��λԪ����ˮƽ����֯�ģ�����Ѷ��ʾ��Ӳ������������ɨ���ߡ����������BITMAPCOREHEADER�ṹ��bcHeight��λ��Ȼ��������������ͼ��ʽ��ͬ���ǣ�DIB��ͼ��ĵ��п�ʼ�����ϱ�ʾͼ��

�ڴ�Ӧ����һЩ���������˵�����С��͡����С�ʱ��ָ���ǵ�����ȷ��ʾ����ʾ����ӡ������ҳ����ʱ����������ͼ��Ķ����͵ײ����ͺ���Ф��Ķ�����ͷ�����������°ͣ���DIB�����еġ���һ�С�ָ����DIB������ɫ�ʶ��ձ����ͼ���У��������С�ָ���ǵ�����ĩ�˵�ͼ���С�

��ˣ���DIB�У�ͼ��ĵ����ǵ����ĵ�һ�У�ͼ��Ķ����ǵ���������һ�С����֮Ϊ���¶��ϵ���֯����Ϊ������֯��ֱ���෴�������ܻ��ʣ�ΪʲôҪ��ô����

�ã��������ǻص�OS/2��Presentation Manager��IBM������ΪPM�ڵ�����ϵͳ�������Ӵ���ͼ�κ͵���ͼ��Ӧ����һ�µġ������������ۣ�������ˣ�������ȫ�������ַ�ʽ�±�̺��Ӵ������¹����ij�ʽд������ΪӦʹ�ô�ֱ������өĻ���������ӵ����ꡣȻ��������ͼ�γ�ʽд������ΪӦʹ�ý������ε���ѧ����������Ѷ��ʾ������һ����ֱ�����ڿռ����������ӵ�ֱ�ǣ���ѿ���������ϵ��

�����֮����ѧ����Ӯ�ˡ�PM�ڵ��������ﶼ�����½�Ϊԭ�㣨�����Ӵ����꣩�����DIBҲ���������ַ�ʽ��

DIBͼ��λԪ
��

DIB���������Ჿ�֣��ڴ�����������DIB���������壩��ʵ�ʵ�DIB��ͼ��λԪ��ɡ�ͼ��λԪ���ɴ�ͼ��ĵ��п�ʼ������ͼ������������ˮƽ����֯�ġ�

DIB�е��������BITMAPCOREHEADER�ṹ��bcHeight��λ��ÿһ�е�ͼ������춸ýṹ��bcWidth��λ��ÿһ�д�����ߵ�ͼ�ؿ�ʼ��ֱ��ͼ����ұߡ�ÿ��ͼ�ص�λԪ�����Դ�bcBitCount��λȡ�ã�Ϊ1��4��8��24��

��λԪ��Ϊ��λ��ÿ�г���ʼ����4�ı������еij��ȿ��Լ���Ϊ��

RowLength = 4 * ((bmch.bcWidth * bmch.bcBitCount + 31) / 32) ;

������C���ø���Ч�ķ�����

RowLength = ((bmch.bcWidth * bmch.bcBitCount + 31) & ~31) >> 3 ;

�����Ҫ����ͨ�����ұ߲����У�ͨ�������㣩����ɳ��ȡ�ͼ�����ϵ���λԪ�������RowLength��bmch.bcHeight�ij˻���

Ҫ�˽�ͼ�ر���ķ�ʽ�������Ƿֱ�������������������ͼ���У�ÿ��λԪ���λԪ��ʾ�ڿ��ڲ��ұ��˺ţ�7��ʾ���λԪ��0��ʾ���λԪ��ͼ��Ҳ���е�����˴�0��ʼ��š�

���ÿͼ��1λԪ��DIB��ÿλԪ���ӦΪ8ͼ�ء�����ߵ�ͼ���ǵ�һ��λԪ������λԪ��


��

ÿ��ͼ�ؿ�����0��1��0��ʾ��ͼ�ص���ɫ��ɫ�ʶ��ձ��е�һ��RGBTRIPLE��Ŀ������1��ʾͼ�ص���ɫ��ɫ�ʶ��ձ��ĵڶ�����Ŀ������

���ÿͼ��4λԪ��DIB��ÿ��λԪ���Ӧ����ͼ�ء�����ߵ�ͼ���ǵ�һ��λԪ��ĸ�4λԪ���Դ����ƣ�


��

ÿͼ��4λԪ��ֵ�ķ�Χ��0��15����ֵ��ָ��ɫ�ʶ��ձ���16����Ŀ��������

���ÿͼ��8λԪ��DIB��ÿ��λԪ��Ϊ1��ͼ�أ�


��

λԪ���ֵ��0��255��ͬ������Ҳ��ָ��ɫ�ʶ��ձ���256����Ŀ��������

���ÿͼ��24λԪ��DIB��ÿ��ͼ����Ҫ3��λԪ���������졢�̺�������ɫֵ��ͼ��λԪ��ÿһ�У������Ͼ���RGBTRIPLE�ṹ�����У�������Ҫ��ÿ�е�ĩ�˲�0�Ա����Ϊ4λԪ��ı�����


��

ÿͼ��24λԪ��DIBû��ɫ�ʶ��ձ���

��չ��Windows DIB
��

��������������Windows 3.0�н��ܵ���OS/2���ݵ�DIB��ͬʱҲ��һ��Windows��DIB����չ�汾��

����DIB��ʽ��ǰ��ĸ�ʽһ������BITMAPFILEHEADER�ṹ��ʼ�����ǽ�����BITMAPINFOHEADER�ṹ��������BITMAPCOREHEADER�ṹ��

typedef struct tagBITMAPINFOHEADER  // bmih
{
     	DWORD 	biSize ;           	// size of the structure = 40
     	LONG  	biWidth ;          	// width of the image in pixels
     	LONG  	biHeight ;         	// height of the image in pixels
     	WORD  	biPlanes ;         	// = 1
     	WORD  	biBitCount ;       	// bits per pixel (1, 4, 8, 16, 24, or 32)
     	DWORD 	biCompression ;  	// compression code
     	DWORD 	biSizeImage ;      	// number of bytes in image
     	LONG  	biXPelsPerMeter ; 	// horizontal resolution
     	LONG  	biYPelsPerMeter ; 	// vertical resolution
     	DWORD 	biClrUsed ;        	// number of colors used
     	DWORD 	biClrImportant ;   	// number of important colors
}
BITMAPINFOHEADER, * PBITMAPINFOHEADER ;

������ͨ�����ṹ�ĵ�һ��λ������OS/2���ݵ�DIB��Windows DIB��ǰ��Ϊ12������Ϊ40��

����ע�⵽��������ṹ�����������ӵ���λ������BITMAPINFOHEADER���Ǽ򵥵���BITMAPCOREHEADER����һЩ����λ���ɡ���ϸ��һ�£���BITMAPCOREHEADER�ṹ�У�bcWidth��bcHeight��λ��16λԪWORDֵ������BITMAPINFOHEADER�ṹ��������32λԪLONGֵ������һ�����������С�仯������������������鷳��

��һ���仯�ǣ����ʹ��BITMAPINFOHEADER�ṹ��1λԪ��4λԪ��8λԪDIB��ɫ�ʶ��ձ�����RGBTRIPLE�ṹ�����С��෴��BITMAPINFOHEADER�ṹ������һ��RGBQUAD�ṹ�����У�

typedef struct tagRGBQUAD  // rgb
{
     	BYTE rgbBlue ;     // blue level
     	BYTE rgbGreen ;    // green level
     	BYTE rgbRed ;      // red level
     	BYTE rgbReserved ; // = 0 
}
RGBQUAD ;

���˰��������趨Ϊ0�ĵ��ĸ���λ�⣬��RGBTRIPLE�ṹ��ͬ�� WINGDI.H��ͷ����Ҳ���������½ṹ��

typedef struct tagBITMAPINFO  		// bmi
{
     	BITMAPINFOHEADER bmiHeader ;      // info-header structure
     	RGBQUAD          		bmiColors[1] ;  // color table array
}
BITMAPINFO, * PBITMAPINFO ;

ע�⣬���BITMAPINFO�ṹ��32λԪ��λַ�߽翪ʼ����ΪBITMAPINFOHEADER�ṹ�ij�����40λԪ�飬����RGBQUAD�����ڵ�ÿһ����ĿҲ��32λ�߽翪ʼ��������ȷ��ͨ��32λԪ΢�������ܸ���Ч�ض�ɫ�ʶ��ձ����϶�ַ��

����BITMAPINFOHEADER�������Windows 3.0�ж���ģ�����������λ��Windows 95��Windows NT 4.0�������¶����ˣ����ұ�����Windows 98��Windows NT 5.0�С��������ڵ��ļ���˵�������biHeight�Ǹ����������ͼ�����϶��µ�DIB��ԭ�������Ͻǡ�����ܺã�������1990��տ�ʼ����DIB��ʽʱ�����������������������ǻ���á��ҵĽ����DZ��⽨�����϶��µ�DIB����һЩ��ʽ�ڱ�дʱû�п��������¡����ԡ�������������biHeight��λʱ�ᵱ����������Microsoft Word 97���е�Microsoft Photo Editor���������϶��µ�DIBʱ�ᱨ�桸ͼ��߶Ȳ��Ϸ�������ȻWord 97���������������

biPlanes��λʼ����1����biBitCount��λ���ڿ�����16��32�Լ�1��4��8��24����Ҳ����Windows 95��Windows NT 4.0�е������ԡ�һ����ҽ�������Щ���Ӹ�ʽ�����ķ�ʽ��

����������������biCompression��biSizeImage��λ��һ������������ǡ�

biXPelsPerMeter��biYPelsPerMeter��λ��ÿ���߶���ͼ�����ֱ�׾�ĵ�λָ��ͼ���ʵ�ʳߴ硣����pel��--picture element��ͼ��Ԫ�أ�--��IBM��ͼ�صijƺ�����Windows���ڲ���ʹ�ô�����Ѷ��Ȼ����Ӧ�ó�ʽ�ܹ���������׼ȷ�Ĵ�С��ʾDIB�����DIB��Դ�û�з�ͼ�ص��豸����Щ��λ�Ǻ����õġ��ڴ����DIB�ڣ���Щ��λ�趨Ϊ0�����ʾû�н����ʵ�ʴ�С��ÿӢ��72��Ľ����ȣ���ʱ�����Ѷ��ʾ��������ʵ�ʽ������������ʾ���Ĵ�С����Լ�൱�ÿ����2835��ͼ�أ�300 DPI����ͨӡ�����Ľ�������ÿ����11,811��ͼ�ء�

biClrUsed�Ƿdz���Ҫ����λ����Ϊ��Ӱ��ɫ�ʶ��ձ�����Ŀ�����������4λԪ��8λԪDIB�����ֱܷ�ָ��ɫ�ʶ��ձ��а�����С�16��256����Ŀ����Ȼ�������ã�������һ����СDIB��С�ķ��������磬����DIBͼ�������64���ҽף�biClrUsed��λ�趨Ϊ64������ɫ�ʶ��ձ�Ϊ256��λԪ���С��ɫ�ʶ��ձ�������64��RGBQUAD�ṹ��ͼ��ֵ�ķ�Χ��0x00��0x3F��DIB��Ȼÿͼ����Ҫ1λԪ�飬��ÿ��ͼ��λԪ��ĸ�2λԪΪ�㡣���biClrUsed��λ�趨Ϊ0����ζ��ɫ�ʶ��ձ���������biBitCount��λ��ʾ��ȫ����Ŀ����

��Windows 95��ʼ��biClrUsed��λ���16λԪ��24λԪ��32λԪDIB����Ϊ���㡣����Щ����£�Windows��ʹ��ɫ�ʶ��ձ�����ͼ��λԪ���෴�أ���ָ��DIB��ɫ�ʶ��ձ��Ĵ�С����ʽʹ�ø���Ѷ���趨��ɫ����256ɫ��Ѷ��ʾ������ʾDIB��������������OS/2���ݸ�ʽ�У�24λԪDIBû��ɫ�ʶ��ձ�����Windows 3.0�е���չ��ʽ�У�Ҳ����һ��������Windows 95�У�24λԪDIB��ɫ�ʶ��ձ���biClrUsed��λָ�������Ĵ�С��

�ܽ����£�

  • ���1λԪDIB��biClrUsedʼ����0��2��ɫ�ʶ��ձ�ʼ����������Ŀ��
    ��
  • ���4λԪDIB�����biClrUsed���0��16����ɫ�ʶ��ձ���16����Ŀ������Ǵ�2��15��������ָ����ɫ�ʶ��ձ��е���Ŀ����ÿ��ͼ�ص����ֵ��С춸�����1��
    ��
  • ���8λԪDIB�����biClrUsed���0��256����ɫ�ʶ��ձ���256����Ŀ������Ǵ�2��225��������ָ����ɫ�ʶ��ձ��е���Ŀ����ÿ��ͼ�ص����ֵ��С춸�����1��
    ��
  • ���16λԪ��24λԪ��32λԪDIB��biClrUsed��λͨ��Ϊ0���������Ϊ0����ָ����ɫ�ʶ��ձ��е���Ŀ����ִ���256ɫ��ʾ����Ӧ�ó�ʽ��ʹ����Щ��Ŀ��ΪDIB�趨��ɫ�̡�
    ��

��һ�����棺ԭ��ʹ������DIB�ļ���д�ij�ʽ��֧Ԯ24λԪDIB�е�ɫ�ʶ��ձ�������ڳ�ʽʹ��24λԪDIB��ɫ�ʶ��ձ��Ļ�����Ҫðһ���ķ��ա�

biClrImportant��λʵ����û��biClrUsed��λ��Ҫ����ͨ�����趨Ϊ0��ָ��ɫ�ʶ��ձ������е���ɫ������Ҫ�ģ���������biClrUsed����ͬ��ֵ�����ַ�����ζ��ͬһ���£���������趨Ϊ0��biClrUsed֮���ֵ������ζ��DIBͼ���ܽ���ͨ��ɫ�ʶ��ձ��е�һ��biClrImportant��Ŀ������ȡ�á�����256ɫ��ʾ���ϲ�����ʾ���������8λԪDIBʱ�����Ǻ����õġ�

���1λԪ��4λԪ��8λԪ��24λԪ��DIB��ͼ��λԪ����֯��OS/2���ݵ�DIB����ͬ�ģ�һ����ҽ�����16λԪ��32λԪDIB��

��ʵ���
��

������һ����������ʽ����˽�����DIBʱ����ϣ�����з���ʲô�����أ�

������Windows3.0�״��Ƴ�ʱ��OS/2��ʽ��DIB�Ѿ����ձ��ˣ���������ָ�ʽȴ�Ѿ����ٳ����ˡ������ʽд������ʵ�ʱ�д����DIB��ʽʱ���������ǡ����������κ�4λԪDIB������Windows�ġ�С���ҡ���ʽʹ��16ɫ��Ѷ��ʾ�������ģ�����Щ��ʾ����ɫ�ʶ��ձ����б�׼��16����ɫ��

���ձ��DIB������ÿͼ��8λԪ��8λԪDIB��Ϊ���ࣺ�ҽ�DIB�ͻ�ɫDIB�����ҵ��ǣ���ͷ��Ѷ�в�û��ָ��8λԪDIB����̬��

����ҽ�DIB��һ�����64��biClrUsed��λ��ָ��ɫ�ʶ��ձ��е�64����Ŀ����Щ��Ŀͨ���������Ļҽײ����У�Ҳ����˵ɫ�ʶ��ձ���00-00-00��04-04-04��08-08-08��0C-0C-0C��RGBֵ��ʼ��������F0-F0-F0��F4-F4-F4��F8-F8-F8��FC-FC-FC��RGBֵ������ɫ�ʶ��ձ��������й�ʽ���㣺

rgb[i].rgbRed = rgb[i].rgbGreen = rgb[i].rgbBlue = i * 256 / 64 ;

������rgb��RGBQUAD�ṹ�����У�i�ķ�Χ��0��63���ҽ�ɫ�ʶ��ձ��������й�ʽ���㣺

rgb[i].rgbRed = rgb[i].rgbGreen = rgb[i].rgbBlue = i * 255 / 63 ;

����˱���FF-FF-FF��β��

ʵ����ʹ���ĸ����㹫ʽ��û��ʲô����������Ѷ��ʾ������ʾ��û�б�6λԪ�����ɫ�ʾ�ȷ�ȡ���һ����ʽ�����������ʵ��Ȼ��������С�64�Ļҽ�ʱ��������16��32���ڴ�����¹�ʽ�ij����ֱ���15��31����ʹ�õڶ�����ʽ���ʺϣ���Ϊ��ȷ����ɫ�ʶ��ձ�������һ����Ŀ��FF-FF-FF��Ҳ���ǰ�ɫ��

��ijЩ8λԪ�ҽ�DIB��ɫ�ʶ��ձ�����64����Ŀʱ�������ҽ׵�DIB����256����Ŀ��biClrUsed��λʵ���Ͽ���Ϊ0��ָ��ɫ�ʶ��ձ�����256����Ŀ�����ߴ�2��256��������Ȼ��biClrUsedֵ��2�Ļ���û���κ����壨��Ϊ������8λԪDIB�ܵ���1λԪDIB�����±��룩����С춻���16��ֵҲû���壨��Ϊ���ܵ���4λԪDIB�����±��룩���κ�����£�ɫ�ʶ��ձ��е���Ŀ��������biClrUsed��λ��ͬ�����biClrUsed��0������256��������ͼ��ֵ���ܳ���ɫ�ʶ��ձ���Ŀ����1��ֵ��������Ϊͼ��ֵ��ָ��ɫ�ʶ��ձ����е����������biClrUsedֵΪ64��8λԪDIB��ͼ��ֵ�ķ�Χ��0x00��0x3F��

������Ӧ��סһ����Ҫ�����飺��8λԪDIB�����������ҽ���ɵ�ɫ�ʶ��ձ���Ҳ����˵������ɫ����ɫ����ɫ�̶����ʱ��������Щ�ҽײ���ɫ�ʶ��ձ��е�����������������������ʱ��ͼ��ֵ�����ʹ����˻�ɫ�ij̶ȡ�Ҳ����˵�����biClrUsed��64����ô0x00ͼ��ֵΪ��ɫ��0x20��ͼ��ֵ��50%�Ļҽף�0x3F��ͼ��ֵΪ��ɫ��

����һЩͼ������ҵ�Ǻ���Ҫ�ģ���Ϊ��������ȫ����ɫ�ʶ��ձ������账��ͼ��ֵ�����Ǻ����õģ�������һ���ʱ��ȥ��BITMAPINFOHEADER�ṹ��һ���򵥵ĸ��ģ��һ�����һ�����ָ��DIBӳ���Dz��ǻҽ׵ģ�����ǣ�DIB��û��ɫ�ʶ��ձ�������ͼ��ֱֵ�Ӵ����ҽס�

��ɫ��8λԪDIBһ��ʹ������ɫ�ʶ��ձ�������biClrUsed��λΪ0��256��Ȼ����Ҳ����������С����ɫ������236������Ӧ����һ����ʵ����ʽͨ��ֻ����Windows��ɫ���ڸ���236����Ŀ����ȷ��ʾ��ЩDIB���ҽ�������������Щ���ݡ�

biXPelsPerMeter��biYPelsPerMeter����Ϊ����ֵ��biClrImportant��λ��Ϊ0��biClrUsedֵ�����Ҳ���١�

DIBѹ��
��

ǰ����û������BITMAPINFOHEADER�е�biCompression��biSizeImage��λ��������������һ����Щֵ��

biCompression��λ����Ϊ�ĸ�����֮һ�������ǣ�BI_RGB��BI_RLE8��BI_RLE4��BI_BITFIELDS�����Ƕ�����WINGDI.H��ͷ�����У�ֵ�ֱ�Ϊ0��3������λ��������;�����4λԪ��8λԪDIB����ָ��ͼ��λԪ����һ�����г��ȣ�run-length�����뷽ʽѹ���ˡ����16λԪ��32λԪDIB����ָ������ɫ���֣�color masking���Ƿ���춶�ͼ��λԪ���б��롣���������Զ�����Windows 95�з����ġ�

���������ǿ�һ��RLEѹ����

  • ���1λԪDIB��biCompression��λʼ����BI_RGB��
    ��
  • ���4λԪDIB��biCompression�������BI_RGB��BI_RLE4��
    ��
  • ���8λԪDIB��biCompression�������BI_RGB��BI_RLE8��
    ��
  • ���24λԪDIB��biCompression��λʼ����BI_RGB��
    ��

���ֵ��BI_RGB��ͼ��λԪ����ķ�ʽ��OS/2���ݵ�DIBһ���������ʹ�����г��ȱ���ѹ��ͼ��λԪ��

���г��ȱ��루RLE����һ����򵥵�����ѹ����ʽ�����Ǹ���DIBӳ����һ���ھ�������ͬ��ͼ���ִ������ʵ���еġ�RLEͨ�����ظ�ͼ�ص�ֵ���ظ��Ĵ�����������ʡ�ռ䣬�����DIB��RLE����ֻ�����˺��ٵľ���DIBͼ��Ҳ����˵�����ε�ijЩ������δ����ģ����ܱ���춱�ʾ�Ǿ���ͼ��

8λԪDIB�����г��ȱ����ڸ����ϸ���һЩ����������Ǵ��������֡���15-1����������⵱biCompression��λ���BI_RGB8ʱ��ͼ��λԪ�ı��뷽ʽ��

��15-1
λԪ��1 λԪ��2 λԪ��3 λԪ��4 ����
00 00     ��β
00 01     ӳ��β
00 02 dx dy �Ƶ���x+dx��y+dy��
00 n = 03��FF     ʹ������n��ͼ��
n = 01��FF ͼ��     �ظ�ͼ��n��

����ѹ����DIB����ʱ���ɳɶԲ鿴DIB����λԪ�飬����˱��ڵġ�λԪ��1���͡�λԪ��2������������ЩλԪ��ֵ�ĵ�����ʽ���У������¶���������������������塣

�����һ��λԪ����㣨��������һ�е����������ô���������г��ȵ��ظ������������ͼ��ֵ���ظ���Σ����磬λԪ���

0x05 0x27

�������ͼ��ֵΪ��

0x27 0x27 0x27 0x27 0x27

��ȻDIB�����������ϲ���ͼ�ص�ͼ�ص��ظ����������ڶ��д��������������ָ����������ͼ����Ӧ���ʹ�á����磺��������

0x00 0x06 0x45 0x32 0x77 0x34 0x59 0x90

�������ͼ��ֵΪ��

0x45 0x32 0x77 0x34 0x59 0x90

��Щ����������2λԪ��Ľ������С�����ڶ���λԪ������������ô�����ھ���һ��δʹ�õĶ���λԪ�顣���磬����

0x00 0x05 0x45 0x32 0x77 0x34 0x59 0x00

�������ͼ��ֵΪ��

0x45 0x32 0x77 0x34 0x59

��������г��ȱ���Ĺ�����ʽ�������Եأ������DIBͼ����û���ظ���ͼ�أ�ʹ�ô�ѹ������ʵ���ϻ�������DIB�����Ĵ�С��

��������ǰ����ָ���˾���DIBͼ���ijЩ���ֿ��Բ�������ķ���������һ�£���д�ij�ʽ����ѹ����DIB���н�ѹ�����������ѹ���ij�ʽ�У���������һ�����֣�x,y������ʼΪ��0,0����ÿ��һ��ͼ�ؽ��룬x��ֵ������1��ÿ���һ�оͽ�x������Ϊ0��������y��ֵ��

����������0x02��λԪ��0x00ʱ������ȡ������λԪ�鲢��������Ϊ�������ŵ��������ӵ�Ŀǰ��x��yֵ�У�Ȼ��������롣����������0x00��0x00ʱ�����ͽ�����һ�У�Ӧ��x��0������yֵ������������0x01��0x00ʱ��������ɽ����ˡ���Щ����׼��DIB������Щδ���������������춶ԷǾ���ͼ��������������λ�����͵�Ӱʱ�dz����ã���Ϊ����ÿһ��Ӱ��������ǰһ�����Ѷ���������±��룩��

���4λԪDIB������һ������ͬ�ģ��������ӣ���ΪλԪ���ͼ��֮�䲻��һ��һ�Ĺ�ϵ��

�����ȡ�ĵ�һ��λԪ����㣬�Ǿ���һ���ظ�����n���ڶ���λԪ�飨���ظ��ģ�����2��ͼ�أ���n��ͼ�صı�����������н�����֡����磬λԪ���

0x07 0x35

��������

0x35 0x35 0x35 0x3?

���е��ʺ�ָ��ͼ�ػ�δ֪�������������ʾ��0x07 0x35�Խ����������λԪ��ԣ�

0x05 0x24

�����������������

0x35 0x35 0x35 0x32 0x42 0x42

���λԪ����еĵ�һλԪ����0x00 ���ڶ���λԪ����0x03�������ʹ�õڶ�λԪ��ָ����ͼ���������磬����

0x00 0x05 0x23 0x57 0x10 0x00

������

0x23 0x57 0x1?

ע���������������ʹ���Ϊż��λԪ�顣

����biCompression��λ��BI_RLE4��BI_RLE8��biSizeImage��λ��ָ����λԪ����DIBͼ�����ϵĴ�С�����biCompression��λ��BI_RGB����biSizeImageͨ��Ϊ0���������ܱ��趨Ϊ����λԪ�鳤�ȵ�biHeight���������ڱ���ǰ������������

Ŀǰ�ļ�˵�����϶��µ�DIB���ܱ�ѹ���������϶��µ�DIB����biHeight��λΪ����������³��ֵġ�

��ɫ���֣�color masking��
��

biCompression��λҲ�������Windows 95���³��ֵ�16λԪ��32λԪDIB�������ЩDIB��biCompression��λ������BI_RGB��BI_BITFIELDS��������Ϊֵ3����

�����ǿ�һ��24λԪDIB��ͼ�ظ�ʽ����ʼ����һ�����BI_RGB��biCompression��λ��

Ҳ����˵��ÿһ�л����϶���RGBTRIPLE�ṹ�����У���ÿ��ĩ���п��ܲ���ֵ��ʹ���ڵ�λԪ����4�ı�����


��

��춾���biCompression��λ���BI_RGB��16λԪDIB��ÿ��ͼ����Ҫ����λԪ�顣��ɫ������������ģ�


��

ÿ����ɫʹ��5λԪ��������ڵĵ�һ��ͼ�أ���ɫֵ�ǵ�һ��λԪ��������λԪ����ɫֵ�ڵ�һ�͵ڶ���λԪ���ж���λԪ����ɫֵ���������λԪ�ǵڶ���λԪ���е��������λԪ����ɫֵ���������λԪ�ǵ�һ��λԪ���е��������λԪ����ɫֵ�ǵڶ���λԪ���е�2��6λԪ���ڶ���λԪ������λԪ��0��

����16λԪ�����ȡͼ��ֵʱ�������������塣��Ϊ���λԪ��ֵ�����λԪ���ȱ����棬ͼ���������£�


��

������wPixel�ڴ�����16λԪͼ�أ����������й�ʽ�����ɫ����ɫ����ɫֵ��

Red   		= 	((0x7C00 & wPixel) 	>> 		10)	<< 3 ;
Green 		= 	((0x03E0 & wPixel) 	>>  		5)	<< 3 ;
Blue  		= 	((0x001F & wPixel) 	>>  		0)	<< 3 ;

���ȣ�ʹ������ֵ��ͼ�ؽ�����λԪAND���㡣�˽���ǣ���ɫ�����ƶ�10λԪ����ɫ�����ƶ�5λԪ����ɫ�����ƶ�0λԪ������Щ�ƶ�ֵ�ҳ�֮Ϊ������ֵ��������Ͳ����˴�0x00��0x1F����ɫֵ����Щֵ���������ƶ�3λԪ�Ժϳɴ�0x00��0xF8����ɫֵ������Щ�ƶ�ֵ�ҳ�֮Ϊ������ֵ������

���ס�����16λԪDIB��ͼ�ؿ�����������ÿ�л���ĩ�˲�������2λԪ����ʹλԪ������ܱ�4������

���32λԪDIB�����biCompression���BI_RGB��ÿ��ͼ����Ҫ4λԪ�顣��ɫֵ�ǵ�һ��λԪ�飬��ɫΪ�ڶ�������ɫΪ������������λԪ����0��Ҳ����ô˵��ͼ����RGBQUAD�ṹ�����С���Ϊÿ��ͼ�صij�����4λԪ�飬����ĩ�˾Ͳ����λԪ�顣

������32λԪ˫�����ȡÿ��ͼ�أ�������������


��

���dwPixel��32λԪ˫���飬

Red   		= 	((0x00FF0000 & dwPixel) >> 		16) << 0 ;
Green 		= 	((0x0000FF00 & dwPixel) >>  		8) 	<< 0 ;
Blue  		= 	((0x000000FF & dwPixel) >> 	 	0) 	<< 0 ;

����ֵȫΪ�㣬��Ϊ��ɫֵ��0xFF�������ע�����˫������Windows GDI��ʽ���������ָ��RGB��ɫ��32λԪCOLORREFֵ��һ�¡���COLORREFֵ�У���ɫռ���λԪ��λԪ�顣

��ĿǰΪֹ�����������˵�biCompression��λΪBI_RGBʱ��16λԪ��32λԪDIB���ڶ���������biCompression��λΪBI_BITFIELDS���������DIB��BITMAPINFOHEADER�ṹ��������32λԪ��ɫ���֣���һ����춺�ɫ���ڶ��������ɫ�������������ɫ������ʹ��C��λԪAND�����ӣ�&������Щ����Ӧ���16λԪ��32λԪ��ͼ��ֵ�ϡ�Ȼ��ͨ������ֵ�����ƶ��������Щֵֻ�м�������������֪������ɫ���ֵĹ���Ӧ�ú���ȷ��ÿ����ɫ����λԪ���ڵ�1�����������ģ�����1��������������λԪ�����ص���

���������ٸ����ӣ��������һ��16λԪDIB������biCompression��λΪBI_BITFIELDS����Ӧ�ü��BITMAPINFOHEADER�ṹ֮���ǰ����˫���飺

0x0000F800
0x000007E0
0x0000001F

ע�⣬��Ϊ����16λԪDIB������ֻ��λ춵ײ�16λԪ��λԪֵ���ܱ��趨Ϊ1�������԰ѱ���dwMask[0]��dwMask[1]��dwMask[2]�趨Ϊ��Щֵ�����ڿ��Ա�д�������м������ƺ�����ֵ��һЩ��ʽ�ˣ�

int MaskToRShift (DWORD dwMask)
{
     	int iShift ;
     	if (	dwMask == 0)
          			return 0 ;

     	for 	(	iShift = 0 ; !(dwMask & 1)  ; iShift++)
          				dwMask >>= 1 ;

     	return iShift ;
}

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 ;
}

Ȼ�����MaskToRShift��ʽ�������������ֵ��

iRShift[0] = MaskToRShift (dwMask[0]) ;
iRShift[1] = MaskToRShift (dwMask[1]) ;
iRShift[2] = MaskToRShift (dwMask[2]) ;

�ֱ�õ�ֵ11��5��0��Ȼ�����MaskToLShift��

iLShift[0] = MaskToLShift (dwMask[0]) ;
iLShift[1] = MaskToLShift (dwMask[1]) ;
iLShift[2] = MaskToLShift (dwMask[2]) ;

�ֱ�õ�ֵ3��2��3�������ܴ�ͼ������ȡÿ����ɫ��

Red  		= ((dwMask[0] & wPixel) >> iRShift[0]) << iLShift[0] ;
Green 		= ((dwMask[1] & wPixel) >> iRShift[1]) << iLShift[1] ;
Blue  		= ((dwMask[2] & wPixel) >> iRShift[2]) << iLShift[2] ;

������ɫ����ܴ��0x0000FFFF������16λԪDIB���������ֵ��֮�⣬������32λԪDIBһ����


ע�⣺

���16λԪ��32λԪDIB����ɫ����ɫ����ɫֵ�ܴ��255��ʵ���ϣ���32λԪDIB�У����������������Ϊ0��������ӦΪ32λԪ��ɫֵ0xFFFFFFFF����Ȼ�����е���ƣ������õ���������⡣


����Windows NT��Windows 95��Windows 98��ʹ����ɫ����ʱ����������ơ����õ�ֵ��ʾ�ڱ�15-2�С�

��15-2
  16λԪDIB 16λԪDIB 32λԪDIB
��ɫ���� 0x00007C00 0x0000F800 0x00FF0000
��ɫ���� 0x000003E0 0x000007E0 0x0000FF00
��ɫ���� 0x0000001F 0x0000001F 0x000000FF
�ټ�Ϊ 5-5-5 5-6-5 8-8-8

���仰˵�����ǵ�biCompression��BI_RGBʱ������ʹ���ڶ����������֣�����ǰ����������ʾ�������顣���������ʾ��һ���ټǷ�����ָ��ÿͼ�غ�ɫ����ɫ����ɫ��λԪ����

��4�汾��Header
��

��˵����Windows 95������һЩԭʼBITMAPINFOHEADER��λ�Ķ��塣Windows 95Ҳ������һ����ΪBITMAPV4HEADER������չ����Ѷ��ͷ�������֪��Windows 95��������Windows 4.0����ͻ����״˽ṹ�������ˣ�Windows NT 4.0Ҳ֧Ԯ�˽ṹ��

typedef struct 
{
DWORD        	bV4Size ;           	// size of the structure = 120
LONG        	bV4Width ;          	// width of the image in pixels
LONG         	bV4Height ;         	// height of the image in pixels
WORD         	bV4Planes ;         	// = 1
WORD         	bV4BitCount ;       	// bits per pixel (1, 4, 8, 16, 24, or 32)
DWORD        	bV4Compression ;    	// compression code
DWORD        	bV4SizeImage ;      	// number of bytes in image
LONG         	bV4XPelsPerMeter ;  	// horizontal resolution
LONG         	bV4YPelsPerMeter ;  	// vertical resolution
DWORD        	bV4ClrUsed ;        	// number of colors used
DWORD        	bV4ClrImportant ; 	    // number of important colors
DWORD        	bV4RedMask ;        	// Red color mask
DWORD        	bV4GreenMask ;      	// Green color mask
DWORD        	bV4BlueMask ;       	// Blue color mask
DWORD        	bV4AlphaMask ;      	// Alpha mask
DWORD        	bV4CSType ;         	// color space type
CIEXYZTRIPLE 	bV4Endpoints ;      	// XYZ values
DWORD        	bV4GammaRed ;       	// Red gamma value
DWORD        	bV4GammaGreen ;     	// Green gamma value
DWORD        	bV4GammaBlue ;      	// Blue gamma value
}
BITMAPV4HEADER, * PBITMAPV4HEADER ;

ע��ǰ11����λ��BITMAPINFOHEADER�ṹ�е���ͬ����5����λ֧ԮWindows 95��Windows NT 4.0��ͼ����ɫ���似��������ʹ��BITMAPV4HEADER�ṹ�����ĸ���λ��������Ӧ��ʹ��BITMAPINFOHEADER����BITMAPV5HEADER����

��bV4Compression��λ���BI_BITFIELDSʱ��bV4RedMask��bV4GreenMask��bV4BlueMask�������16λԪ��32λԪDIB��������Ϊ������BITMAPINFOHEADER�ṹ�е���ɫ���������ͬ�ĺ�ʽ�����ҵ�ʹ�ó�����ȷ�Ľṹ��λ֮���ԭʼ�ṹʱ������ʵ���ϳ�����DIB��������ͬλ�á�������֪��bV4AlphaMask��λ����ʹ�á�

BITMAPV5HEADER�ṹʣ�����λ������Windows��ɫ������Image Color Management�������������ݳ�Խ�˱���ķ�Χ�������˽�һЩ������������档

Ϊɫ��ʹ��RGB������������춣����������Ѷ��ʾ������ɫ������Ͳ�ɫɨ��������ʾ�����������ɫָ��ΪRGBֵ��255,0,0������ζ�����ĵ�ѹӦ�üӵ��������߹��ڵĺ�ɫ����ǹ�ϣ�RGBֵ��128,0,0����ʾʹ��һ���ѹ����ͬ��ʾ���������ͬ��Ч�������ң�ӡ����ʹ���˲�ͬ����ɫ��ʾ����������ɫ�����ɫ����ɫ�ͺ�ɫ����ϱ�ʾ��ɫ����Щ������֮ΪCMY��cyan-magenta-yellow����ɫ-���ɫ-��ɫ����CMYK�� cyan-magenta-yellow-black����ɫ-���ɫ-��ɫ-��ɫ ������ѧ��ʽ�ܰ�RGBֵת��ΪCMY��CMYK�������ܱ�֤ӡ������ɫ����ʾ����ɫ����ϡ���ɫ�ʵ��似�����ǰ���ɫ���װ���޹صı�׼��ϵ������һ�ֳ��ԡ�

��ɫ��������ɼ���IJ����йأ������ķ�Χ��380nm��������780nm���죩֮�䡣һ�������ܲ���Ĺ����ǿɼ������ڲ�ͬ��������ϡ�1931�꣬Commission Internationale de L'Eclairage (International Commission on Illumination)��CIE������һ�ֿ�ѧ������ɫ�ķ����������ʹ��������ɫ���亯��������Ϊx��y��z������������ʡ�Ե���ʽ������ÿ5nm��ֵ��������CIE Publication 15.2-1986����Colorimetry��Second Edition���ı�2.1�С�

��ɫ�Ĺ��ף�S����һ��ָ��ÿ������ǿ�ȵ�ֵ�����֪�����ף����ܹ�������ɫ��صĺ���Ӧ�õ�����������X��Y��Z��


��

��Щֵ��Ϊ ï¿½ï¿½X����Y�ʹ�Z ï¿½ï¿½y��ɫƥ�亯ʽ������۶Է�Χ�ڿɼ������ڹ��ߵķ�Ӧ����������ȥ��һ����380nm��780nm��0��ʱ�������ߣ���Y��֮ΪCIE���ȣ���Ϊ��ָ���˹��ߵ�����ǿ�ȡ�

���ʹ��BITMAPV5HEADER�ṹ��bV4CSType��λ�ͱ����趨ΪLCS_CALIBRATED_RGB����ֵΪ0�����ĸ�λԪ������趨Ϊ��Чֵ��

CIEXYZTRIPLE�ṹ�������·�ʽ���壺

typedef struct tagCIEXYZTRIPLE
{
     	CIEXYZ  ciexyzRed ;
     	CIEXYZ  ciexyzGreen ;
     	CIEXYZ  ciexyzBlue ;
}
CIEXYZTRIPLE, * LPCIEXYZTRIPLE ;

��CIEXYZ�ṹ�������£�

typedef struct tagCIEXYZ
{
     	FXPT2DOT30 ciexyzX ;
     	FXPT2DOT30 ciexyzY ;
     	FXPT2DOT30 ciexyzZ ;
}
CIEXYZ, * LPCIEXYZ ;

��������λ����ΪFXPT2DOT30ֵ����ζ�������Ǵ���2λԪ�������ֺ�30λԪС�����ֵĶ���ֵ��������0x40000000��1.0��0x48000000��1.5�����ֵ0xFFFFFFFF����4.0Сһ��㡣

bV4Endpoints��λ�ṩ��������RGB��ɫ��255,0,0������0,255,0���ͣ�0,0,255����ص�X��Y��Zֵ����ЩֵӦ���ɽ���DIB��Ӧ�ó�ʽ������ָ����ЩRGB��ɫ��װ���޹ص����塣

BITMAPV4HEADERʣ���������λָ��٤��ֵ����ϣ����Сд��ĸ�ã�����ָ����ɫ�ȼ�����ڵķ����ԡ���DIB�ڣ��졢�̡����ķ�Χ��0��225������ʾ���ϣ���������ֵ��ת��Ϊ��ʾ��ʹ�õ�������ȵ�ѹ����ѹ������ÿ��ͼ�ص�ǿ�ȡ�Ȼ��������������߹��е���ǹ�ĵ������ԣ�ͼ�ص�ǿ�ȣ�I���������ѹ��V��������أ����ǵĹ�ϵΪ��


��

��������ʾ���ġ����ȡ������趨�ĺ�ɫ�ȼ�������ֵΪ0����ָ�� ������ʾ���ġ�ͼ�񡹻򡸶Աȶȡ������趨�ġ���춴������ʾ�����ô�Լ��2.5���ҡ�

Ϊ�˶Դ˷�����������������Ӱ������·�ڰ����ˡ�٤����������ָ��0.45�����˽�����Ӱ���Ĺ��ߣ�����ζ����Ѷ��ʾ����٤��Ϊ2.2������Ѷ��ʾ���ĸ�٤��ֵ�����˶Աȶȣ���ͨ���Dz���Ҫ�ģ���Ϊ��Χ�Ĺ��߸��ʺ�춵ͶԱȶȡ���

��Ѷ��ʾ������������Է�Ӧʵ�����Ǻ��ʵ��ģ�������Ϊ����Թ��ߵķ�ӦҲ�Ƿ����Եġ����������Y����ΪCIE���ȣ��������ԵĹ��߶�����CIEҲ������һ���ӽ������о�������ֵ��������L* (����Ϊ "ell star") ��ͨ��ʹ�����¹�ʽ��Y����õ��ģ�


��

�ڴ�Yn�ǰ�ɫ�ȼ�����ʽ�ĵ�һ������һ��С�����Բ��֡�һ�㣬��������ȸо������������ȵ���������صģ����ɵڶ�����ʽָ����L* �ķ�Χ��0��100��ÿ��L* �����Ӷ��ٶ��������ܸо��������ȵ���С�仯��

����֪�����ȶ������������ȶԹ���ǿ�ȱ���Ҫ����һЩ����ʹ��λԪ���������ٵ�һ�������ij̶Ȳ����������·��Ҳ��������Ѷ��

����������һ����������ͼ��ֵ (P)��Χ��0��255����������ת���ɵ�ѹ�ȼ������Ǽٶ���׼��Ϊ0.0��1.0֮���ֵ��������ʾ���ĺ�ɫ���趨Ϊ0����ͼ�ص�ǿ��Ϊ��


��

����ô�ԼΪ2.5������о������� (L*)����춴�ǿ�ȵ��������ͱ仯��0��100�ķ�Χ����˴�Լ�ǣ�


��

ָ��ֵ��ԼΪ0.85�����ָ��ֵΪ1����ôCIE������ͼ��ֵ��ȫƥ�䡣��Ȼ����ȫ������������������ͼ��ֵָ�����������Ⱦͷdz��ӽ���

BITMAPV4HEADER������������λΪ����DIB�ij�ʽ�ṩ��һ��Ϊͼ��ֵָ�������٤��ֵ�ķ�������Щֵ��16λԪ����ֵ��16λԪ��С��ֵ˵�������磬0x10000Ϊ1.0�����DIB�Dz�׽ʵ��Ӱ��������ģ�Ӱ��׽Ӳ��Ϳ��ܰ������٤��ֵ�����ҿ�����2.2������Ϊ0x23333�������DIB���ɳ�ʽͨ�����㷨�����ģ���ʽ��ʹ��һ����ʽ����ʹ�õ��κ���������ת��ΪCIE���ȡ�

��5���Header
��

ΪWindows 98��Windows NT 5.0(��Windows 2000)��д�ij�ʽ��ʹ��ӵ���µ�BITMAPV5HEADER��Ѷ�ṹ��DIB��

typedef struct 
{
DWORD        	bV5Size ;           	// size of the structure = 120
LONG         	bV5Width ;          	// width of the image in pixels
LONG         	bV5Height ;         	// height of the image in pixels
WORD         	bV5Planes ;         	// = 1
WORD         	bV5BitCount ;       	// bits per pixel (1,4,8,16,24,or32)
DWORD        	bV5Compression ;    	// compression code
DWORD        	bV5SizeImage ;      	// number of bytes in image
LONG         	bV5XPelsPerMeter ;  	// horizontal resolution
LONG         	bV5YPelsPerMeter ;  	// vertical resolution
DWORD        	bV5ClrUsed ;        	// number of colors used
DWORD        	bV5ClrImportant ;   	// number of important colors
DWORD        	bV5RedMask ;        	// Red color mask
DWORD        	bV5GreenMask ;      	// Green color mask
DWORD        	bV5BlueMask ;       	// Blue color mask
DWORD        	bV5AlphaMask ;      	// Alpha mask
DWORD        	bV5CSType ;         	// color space type
CIEXYZTRIPLE 	bV5Endpoints ;      	// XYZ values
DWORD        	bV5GammaRed ;       	// Red gamma value
DWORD        	bV5GammaGreen ;     	// Green gamma value
DWORD        	bV5GammaBlue ;      	// Blue gamma value
DWORD        	bV5Intent ;         	// rendering intent
DWORD        	bV5ProfileData ;    	// profile data or filename
DWORD        	bV5ProfileSize ;    	// size of embedded data or filename
DWORD        	bV5Reserved ;
}
BITMAPV5HEADER, * PBITMAPV5HEADER ;

�������ĸ�����λ��ֻ�������������á���Щ��λ֧ԮICC Profile Format Specification�������ɡ�����ɫ��Э�ᣨInternational Color Consortium����(��Adobe��Agfa��Apple��Kodak��Microsoft��Silicon Graphics��Sun Microsystems��������˾���)�����ġ������� http://www.icc.org ï¿½ï¿½È¡ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½×¼ï¿½Ä¸ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ï£ï¿½Ã¿ï¿½ï¿½ï¿½ï¿½ï¿½ë£¨É¨ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ó°ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ó¡ï¿½ï¿½ï¿½ï¿½ï¿½Í½ï¿½Æ¬ï¿½ï¿½Â¼ï¿½ï¿½ï¿½ï¿½ï¿½Ô¼ï¿½ï¿½ï¿½Ê¾ï¿½ï¿½ï¿½ï¿½Ê¾ï¿½ï¿½ï¿½ï¿½ï¿½è±¸ï¿½ë½«Ô­Ê¼×°ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½É«ï¿½ï¿½Ò»ï¿½ï¿½ÎªRGB��CMYK����ϵ��װ���޹���ɫ�����趨�����йأ���������CIE XYZֵ��������ɫ����Щ�趨�����ĸ�������.ICM��ָ��ͼ����ɫ������image color management�������趨������Ƕ��DIB������DIB����������ָ������DIB�ķ�ʽ��������/Platform SDK/Graphics and Multimedia Services/Color Management��ȡ���й�Windows��ͼ����ɫ����������ϸ��Ѷ��

BITMAPV5HEADER��bV5CSType��λ��ӵ�м�����ͬ��ֵ�������LCS_CALIBRATED_RGB����ô������BITMAPV4HEADER�ṹ���ݡ�bV5Endpoints��λ��٤����λ������Ч��

���bV5CSType��λ��LCS_sRGB���Ͳ����趨ʣ�����λ��Ԥ�����ɫ�ռ��ǡ���׼����RGB��ɫ�ռ䣬������Microsoft��Hewlett-Packard��ҪΪInternet��Ƶģ�������װ���޹ص����ݶ�����Ҫ�������趨���������ļ�λ�http://www.color.org/contrib/sRGB.html��

���bV5CSType��λ��LCS_Windows_COLOR_SPACE���Ͳ����趨ʣ�����λ��Windowsͨ��API��ʽ����ʹ��Ԥ�����ɫ�ռ���ʾ����ͼ��

���bV5CSType��λ��PROFILE_EMBEDDED����DIB��������һ��ICC�趨�����������λ��PROFILE_LINKED��DIB�����Ͱ�����ICC�趨����������·���͵������ơ�������������£�bV5ProfileData���Ǵ�BITMAPV5HEADER��ʼ���趨�������ϻ򵵰�������ʼλ�õ�ƫ������bV5ProfileSize��λ���������ϻ򵵰����Ĵ�С�������趨bV5Endpoints��٤����λ��

��ʾDIB��Ѷ
��

��������������һЩ��ʽ�롣ʵ�������Dz���δ����˽���ʾDIB��֪ʶ���������ܱ���ͷ�ṹ����ʾ�й�DIB����Ѷ�����ʽ15-1 DIBHEADS��ʾ��

 ï¿½ï¿½Ê½15-1  DIBHEADS
DIBHEADS.C
/*---------------------------------------------------------------------------
   	DIBHEADS.C -- 	Displays DIB Header Information
                 		(c) Charles Petzold, 1998
---------------------------------------------------------------------------*/

#include <windows.h>
#include "resource.h"

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
TCHAR szAppName[] = TEXT ("DibHeads") ;
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, TEXT ("DIB Headers"),
                          		WS_OVERLAPPEDWINDOW,
                          		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 ;
}

void Printf (HWND hwnd, TCHAR * szFormat, ...)
{
     	TCHAR   		szBuffer [1024] ;
     	va_list 	pArgList ;

     	va_start (pArgList, szFormat) ;
     	wvsprintf (szBuffer, szFormat, pArgList) ;
     	va_end (pArgList) ;

     	SendMessage (hwnd, EM_SETSEL, (WPARAM) -1, (LPARAM) -1) ;
     	SendMessage (hwnd, EM_REPLACESEL, FALSE, (LPARAM) szBuffer) ;
     	SendMessage (hwnd, EM_SCROLLCARET, 0, 0) ;
}
void DisplayDibHeaders (HWND hwnd, TCHAR * szFileName)
{
 static TCHAR   * szInfoName []= { TEXT ("BITMAPCOREHEADER"), 
                                    TEXT 	("BITMAPINFOHEADER"),
                                    TEXT 	("BITMAPV4HEADER"),
                                    TEXT 	("BITMAPV5HEADER") } ;
Static TCHAR  * szCompression []={TEXT ("BI_RGB"), 
TEXT    ("BI_RLE8"),
                                    TEXT 	("BI_RLE4"),
                                    TEXT 	("BI_BITFIELDS"),
                                    TEXT 	("unknown") } ;
	BITMAPCOREHEADER 	* 	pbmch ;
	BITMAPFILEHEADER 	* 	pbmfh ;
	BITMAPV5HEADER	* 	pbmih ;
	BOOL 				bSuccess ;
	DWORD       		dwFileSize, dwHighSize, dwBytesRead ;
	HANDLE            	hFile ;
   	int                 i ;
  	PBYTE               pFile ;
  	TCHAR              * szV ;

        			// Display the file name

     	Printf (hwnd, TEXT ("File: %s\r\n\r\n"), szFileName) ;
          			// Open the file
     	hFile = CreateFile (szFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
        OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL) ;
     	if (hFile == INVALID_HANDLE_VALUE)
     	{
          			Printf (hwnd, TEXT ("Cannot open file.\r\n\r\n")) ;
          			return ;
     }
          
          			// Get the size of the file
     	dwFileSize = GetFileSize (hFile, &dwHighSize) ;
     	if (dwHighSize)
     	{
          		Printf (hwnd, TEXT ("Cannot deal with >4G files.\r\n\r\n")) ;
          		CloseHandle (hFile) ;
          		return ;
     }
          			// Allocate memory for the file
     	pFile = malloc (dwFileSize) ;
     	if (!pFile)
     	{
          		Printf (hwnd, TEXT ("Cannot allocate memory.\r\n\r\n")) ;
          		CloseHandle (hFile) ;
          		return ;
     	}

          				// Read the file
     	SetCursor (LoadCursor (NULL, IDC_WAIT)) ;
     	ShowCursor (TRUE) ;

     	bSuccess = ReadFile (hFile, pFile, dwFileSize, &dwBytesRead, NULL) ;
     	ShowCursor (FALSE) ;
     	SetCursor (LoadCursor (NULL, IDC_ARROW)) ;

     	if (!bSuccess || (dwBytesRead != dwFileSize))
     	{
          			Printf (hwnd, TEXT ("Could not read file.\r\n\r\n")) ;
          			CloseHandle (hFile) ;
			free (pFile) ;
   			return ;
     	}

          				// Close the file
     	CloseHandle (hFile) ;
          				// Display file size
     	Printf (hwnd, TEXT ("File size = %u bytes\r\n\r\n"), dwFileSize) ;
          				// Display BITMAPFILEHEADER structure
     	pbmfh = (BITMAPFILEHEADER *) pFile ;
     	Printf 	(hwnd, 	TEXT 	("BITMAPFILEHEADER\r\n")) ;
     	Printf 	(hwnd, 	TEXT 	("\t.bfType = 0x%X\r\n"), pbmfh->bfType) ;
     	Printf 	(hwnd, 	TEXT 	("\t.bfSize = %u\r\n"), pbmfh->bfSize) ;
     	Printf 	(hwnd, 	TEXT 	("\t.bfReserved1 = %u\r\n"), pbmfh->bfReserved1) ;
     	Printf	(hwnd, 	TEXT 	("\t.bfReserved2 = %u\r\n"), pbmfh->bfReserved2) ;
     	Printf	(hwnd, 	TEXT 	("\t.bfOffBits = %u\r\n\r\n"), pbmfh->bfOffBits) ;

          				// Determine which information structure we have

     	pbmih = (BITMAPV5HEADER *) (pFile + sizeof (BITMAPFILEHEADER)) ;
     	switch (pbmih->bV5Size)
     	{
     	case 	sizeof 	(BITMAPCOREHEADER):i= 0 ; break ;
     	case 	sizeof 	(BITMAPINFOHEADER): i= 1 ; szV= 
TEXT ("i") ; 	break ;
     	case 	sizeof 	(BITMAPV4HEADER):i= 2 ; szV= 
TEXT ("V4") ; 	break ;
     	case 	sizeof 	(BITMAPV5HEADER):i= 3 ; szV= 
TEXT ("V5") ; 	break ;
     	default:
Printf (hwnd, 	  TEXT ("Unknown header size of %u.\r\n\r\n"), 
                        	pbmih->bV5Size) ;
        		free (pFile) ;
         		return ;
     	}

     	Printf (hwnd, TEXT ("%s\r\n"), szInfoName[i]) ;
          					// Display the BITMAPCOREHEADER fields
     	if (pbmih->bV5Size == sizeof (BITMAPCOREHEADER))
     	{
          		pbmch = (BITMAPCOREHEADER *) pbmih ;
Printf(hwnd,TEXT("\t.bcSize = %u\r\n"), pbmch->bcSize) ;
Printf(hwnd,TEXT("\t.bcWidth = %u\r\n"), pbmch->bcWidth) ;
Printf(hwnd,TEXT("\t.bcHeight = %u\r\n"), pbmch->bcHeight) ;
Printf(hwnd,TEXT("\t.bcPlanes = %u\r\n"), pbmch->bcPlanes) ;
Printf(hwnd,TEXT("\t.bcBitCount = %u\r\n\r\n"), pbmch->bcBitCount) ;
      free (pFile) ;
      return ;
     }

          			// Display the BITMAPINFOHEADER fields
Printf(hwnd,TEXT("\t.b%sSize = %u\r\n"), szV, pbmih->bV5Size) ;
Printf(hwnd,TEXT("\t.b%sWidth = %i\r\n"), szV, pbmih->bV5Width) ;
Printf(hwnd,TEXT("\t.b%sHeight = %i\r\n"), szV, pbmih->bV5Height) ;
Printf(hwnd,TEXT("\t.b%sPlanes = %u\r\n"), szV, pbmih->bV5Planes) ;
Printf(hwnd,TEXT("\t.b%sBitCount=%u\r\n"),szV, pbmih->bV5BitCount) ;
Printf(hwnd,TEXT("\t.b%sCompression = %s\r\n"), szV,
			      szCompression [min (4, pbmih->bV5Compression)]) ;
Printf(hwnd,TEXT("\t.b%sSizeImage= %u\r\n"),szV, 
pbmih->bV5SizeImage) ;
Printf(hwnd,TEXT ("\t.b%sXPelsPerMeter = %i\r\n"), szV, 
           	      pbmih->bV5XPelsPerMeter) ;
Printf(hwnd,TEXT ("\t.b%sYPelsPerMeter = %i\r\n"), szV, 
       		 	  pbmih->bV5YPelsPerMeter) ;
Printf 	(hwnd,	TEXT ("\t.b%sClrUsed = %i\r\n"), szV, 
pbmih->bV5ClrUsed) ;
Printf	(hwnd,	TEXT ("\t.b%sClrImportant = %i\r\n\r\n"), szV, 
                  pbmih->bV5ClrImportant) ;

     	if (pbmih->bV5Size == sizeof (BITMAPINFOHEADER))
     {
          			if (pbmih->bV5Compression == BI_BITFIELDS)
          {
Printf (hwnd,TEXT("Red Mask = %08X\r\n"), pbmih->bV5RedMask) ;
Printf (hwnd,TEXT ("Green Mask = %08X\r\n"), pbmih->bV5GreenMask) ;
Printf (hwnd,TEXT ("Blue Mask  = %08X\r\n\r\n"), pbmih->bV5BlueMask) ;
          }
          		free (pFile) ;
          		return ;
     }

          				// Display additional BITMAPV4HEADER fields
     	Printf (hwnd, 	TEXT ("\t.b%sRedMask   = %08X\r\n"), szV, 
                   						pbmih->bV5RedMask) ;
     	Printf (hwnd, 	TEXT ("\t.b%sGreenMask = %08X\r\n"), szV, 
                   						pbmih->bV5GreenMask) ;
     	Printf (hwnd, 	TEXT ("\t.b%sBlueMask  = %08X\r\n"), szV, 
                   						pbmih->bV5BlueMask) ;
     	Printf (hwnd, 	TEXT ("\t.b%sAlphaMask = %08X\r\n"), szV, 
                   						pbmih->bV5AlphaMask) ;
     	Printf (hwnd, 	TEXT ("\t.b%sCSType = %u\r\n"), szV, 
                   						pbmih->bV5CSType) ;
 	Printf (hwnd, 	TEXT ("\t.b%sEndpoints.ciexyzRed.ciexyzX = %08X\r\n"),  
     						szV, pbmih->bV5Endpoints.ciexyzRed.ciexyzX) ;
	Printf (hwnd, 	TEXT ("\t.b%sEndpoints.ciexyzRed.ciexyzY = %08X\r\n"), 
      						szV, pbmih->bV5Endpoints.ciexyzRed.ciexyzY) ;
	Printf (hwnd, 	TEXT ("\t.b%sEndpoints.ciexyzRed.ciexyzZ = %08X\r\n"), 
       						szV, pbmih->bV5Endpoints.ciexyzRed.ciexyzZ) ;
	Printf (hwnd, 	TEXT ("\t.b%sEndpoints.ciexyzGreen.ciexyzX = %08X\r\n"), 
    						szV, pbmih->bV5Endpoints.ciexyzGreen.ciexyzX) ;
	Printf (hwnd, 	TEXT ("\t.b%sEndpoints.ciexyzGreen.ciexyzY = %08X\r\n"), 
      						szV, pbmih->bV5Endpoints.ciexyzGreen.ciexyzY) ;
 	Printf (hwnd, 	TEXT ("\t.b%sEndpoints.ciexyzGreen.ciexyzZ = %08X\r\n"), 
      						szV, pbmih->bV5Endpoints.ciexyzGreen.ciexyzZ) ;
	Printf (hwnd, 	TEXT ("\t.b%sEndpoints.ciexyzBlue.ciexyzX = %08X\r\n"),
						szV, pbmih->bV5Endpoints.ciexyzBlue.ciexyzX) ;
	Printf (hwnd, 	TEXT ("\t.b%sEndpoints.ciexyzBlue.ciexyzY = %08X\r\n"), 
						szV, pbmih->bV5Endpoints.ciexyzBlue.ciexyzY) ;
	Printf (hwnd, 	TEXT ("\t.b%sEndpoints.ciexyzBlue.ciexyzZ = %08X\r\n"), 
						szV, pbmih->bV5Endpoints.ciexyzBlue.ciexyzZ) ;
	Printf (hwnd, 	TEXT ("\t.b%sGammaRed = %08X\r\n"), szV, 
						pbmih->bV5GammaRed) ;
	Printf (hwnd,	TEXT ("\t.b%sGammaGreen = %08X\r\n"), szV, 
						pbmih->bV5GammaGreen) ;
	Printf (hwnd,	TEXT ("\t.b%sGammaBlue  = %08X\r\n\r\n"), szV, 
						pbmih->bV5GammaBlue) ;

	if (pbmih->bV5Size == sizeof (BITMAPV4HEADER))
	{
	free (pFile) ;
	return ;
     }

		// Display additional BITMAPV5HEADER fields
	Printf 		(hwnd,		TEXT ("\t.b%sIntent = %u\r\n"), szV, pbmih->bV5Intent) ;
	Printf 	(hwnd,	TEXT ("\t.b%sProfileData = %u\r\n"), szV, 
							pbmih->bV5ProfileData) ;
	Printf 	(hwnd,	TEXT ("\t.b%sProfileSize = %u\r\n"), szV, 
							pbmih->bV5ProfileSize) ;
	Printf 	(hwnd,	TEXT ("\t.b%sReserved = %u\r\n\r\n"), szV, 
							pbmih->bV5Reserved) ;

 	free (pFile) ;
  	return ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static HWND			hwndEdit ;
	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") ;
     
	switch (message)
	{
	case 	WM_CREATE:
			hwndEdit = CreateWindow (TEXT ("edit"), NULL,
					WS_CHILD | WS_VISIBLE | WS_BORDER | 
					WS_VSCROLL | WS_HSCROLL |
					ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY, 
					0, 0, 0, 0, hwnd, (HMENU) 1,
					 ((LPCREATESTRUCT) lParam)->hInstance, NULL) ;

		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:
			MoveWindow (hwndEdit, 0, 0, LOWORD (lParam), HIWORD (lParam), TRUE) ;
          			return 0 ;

     	case 	WM_COMMAND:
          			switch (LOWORD (wParam))
          			{
          			case 	IDM_FILE_OPEN:
               					if (GetOpenFileName (&ofn))
                    DisplayDibHeaders (hwndEdit, szFileName) ;

               					return 0 ;
          			}
          		break ;
     
     	case 	WM_DESTROY:
          			PostQuitMessage (0) ;
          			return 0 ;
	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}
 DIBHEADS.RC ��ժ¼��
//Microsoft Developer Studio generated resource script.
#include "resource.h"
#include "afxres.h"

///////////////////////////////////////////////////////////////////////////
// Accelerator
DIBHEADS ACCELERATORS DISCARDABLE 
BEGIN
    	"O",            IDM_FILE_OPEN,          	VIRTKEY, CONTROL, NOINVERT
END

///////////////////////////////////////////////////////////////////////////
// Menu
DIBHEADS MENU DISCARDABLE 
BEGIN
    	POPUP "&File"
    	BEGIN
        		MENUITEM "&Open\tCtrl+O", 	IDM_FILE_OPEN
    	END
END
 RESOURCE.H ��ժ¼��
// Microsoft Developer Studio generated include file.
// Used by DibHeads.rc

#define IDM_FILE_OPEN                40001

�˳�ʽ��һ����̵�WndProc��ʽ����������һ��Ψ���ı༭�Ӵ�������������ʾ������Ҳ�������ܱ��ϵġ�File Open�������ͨ������GetOpenFileName��ʽʹ�ñ�׼�ġ�File Open���Ի����飬Ȼ�����DisplayDibHeaders��ʽ���˺�ʽ������DIB������������岢��������ʾ���еı�ͷ��Ѷ��

��ʾ����ӡ
��

����ͼ���������ġ�����һ���У����ǿ�һ��Windows����Ѷ��ʾ���ϻ���ӡҳ����֧Ԯ��ʾDIB��������ʽ��Ҫ�õ����õ����ܣ�������ʹ��һ�ֶ�Ȧ�ӵķ�������ʾ����ͼ���һ��ڱ��µ��������۸÷����������о���������ʽ���һЩ��

��������ʽ��ΪSetDIBitsToDevice������Ϊ��set dee eye bits to device������StretchDIBits ������Ϊ��stretch dee eye bits������ÿ����ʽ��ʹ�ô����ڼ������е�DIB������ʾ����DIB�����ľ��β��֡���ʹ��SetDIBitsToDeviceʱ����ͼ��Ϊ��λ����ʾӳ��Ĵ�С��DIB��ͼ�ش�С��ͬ�����磬һ��640��480��DIB��ռ��������׼��VGAөĻ������300dpi������ӡ��������ֻ��Լ2.1��1.6Ӣ�硣StretchDIBits���������СDIB�ߴ���к��дӶ�������豸����ʾһ���ض��Ĵ�С��

�˽�DIB
��

������������ʽ֮һ����ʾDIBʱ������Ҫ�������ͼ�����Ѷ��������ǰ��˵���ģ�DIB�����������в��֣�


��

DIB�����ܱ���������塣������˵�����ͷ�⣬���������������ڼ���������������У�ָ��ü�����鿪ʼ����Ҳ������Ѷ��ͷ�Ŀ�ͷ����ָ�걻��Ϊָ��packed DIB��ָ�꣨����ͼ����


��

����ͨ������������DIBʱ���õĸ�ʽ������Ҳ������DIB������ˢʱ���õĸ�ʽ����Ϊ����DIB�ɵ���ָ�꣨��pPackedDib�����ã�����packed DIB���ڼ������д���DIB�ķ��㷽���������԰�ָ�궨��Ϊָ��BYTE��ָ�ꡣʹ�ñ���ǰ����ʾ�Ľṹ���壬�ܵõ����д�����DIB�ڵ���Ѷ������ɫ�ʶ��ձ��͸���ͼ��λԪ��

Ȼ����Ҫ��õ���ô����Ѷ������ҪһЩ��ʽ�롣���磬������ͨ�����������򵥵�ȡ��DIB��ͼ�ؿ��ȣ�

iWidth = ((PBITMAPINFOHEADER) pPackedDib)->biWidth ;

DIB�п�����OS/2���ݸ�ʽ�ġ������ָ�ʽ�У�packed DIB��BITMAPCOREHEADER�ṹ��ʼ������DIB��ͼ�ؿ��Ⱥ͸߶���16λԪWORD��������32λԪLONG���档��ˣ����ȱ�����DIB�Ƿ�Ϊ�ɵĸ�ʽ��Ȼ��������Ӧ�IJ�����

if (((PBITMAPCOREHEADER) pPackedDib)->bcSize == sizeof (BITMAPCOREHEADER))
     	iWidth = ((PBITMAPCOREHEADER) pPackedDib)->bcWidth ;
else
     	iWidth = ((PBITMAPINFOHEADER) pPackedDib)->biWidth ;

��Ȼ���ⲻ���㣬��������������ϲ�õ�������

������һ������Ȥ��ʵ�飺����һ��ָ��packed DIB��ָ�꣬����Ҫ�ҳ�λ����꣨5,27����ͼ��ֵ����ʹ�ٶ�DIB����OS/2���ݵĸ�ʽ����Ҳ��Ҫ�˽�DIB�Ŀ��ȡ��߶Ⱥ�λԪ��������Ҫ����ÿһ��ͼ�ص�λԪ�鳤�ȣ�ȷ��ɫ�ʶ��ձ��ڵ���Ŀ�����Լ�ɫ�ʶ��ձ��Ƿ��������32λԪ����ɫ���֡���������DIB�Ƿ�ѹ���������������ͼ���Dz���ֱ����λַ�õ��ġ�

�������Ҫֱ�Ӵ�ȡ���е�DIBͼ�أ���������ͼ�δ�������һ����������ܻ�����һ�㴦��ʱ�䡣������ԭ�򣬴���һ��ָ��packed DIB��ָ��ͺܷ����ˣ������Ⲣ����һ����Ч�ʵĽ����ʽ����һ��Ư���Ľ��������ΪDIB����һ�������㹻��Ա���ϵ�C++��𣬴Ӷ�������������ش�ȡDIBͼ�ء�Ȼ������������Ӧ�����ڱ����������˽�C++���ҽ�����һ��˵��һ��C�Ľ��������

���SetDIBitsToDevice��StretchDIBits��ʽ����Ҫ����Ѷ����һ��ָ��DIB��BITMAPINFO�ṹ��ָ�ꡣ��Ӧ������BITMAPINFO�ṹ��BITMAPINFOHEADER�ṹ��ɫ�ʶ��ձ���ɡ���������һ��ָ��packed DIB��ָ�ꡣ

��ʽҲ��Ҫһ��ָ��ͼ��λԪ��ָ�ꡣ���ܳ�ʽ��д�úܲ�Ư���������ָ�껹�ǿ��Դ���Ѷ��ͷ�ڵ���Ѷ�Ƴ���ע�⣬������ȡBITMAPFILEHEADER�ṹ��bfOffBits��λʱ�����ָ���ܺ����׵ؼ������bfOffBits��λָ���˴�DIB�����Ŀ�ͷ��ͼ��λԪ��ƫ�����������Լ򵥵ذѴ�ƫ�����ӵ�BITMAPINFOָ���У�Ȼ���ȥBITMAPFILEHEADER�ṹ�Ĵ�С��Ȼ���������Ӽ������ϵõ�ָ��packed DIB��ָ��ʱ���Ⲣ�������ã���Ϊû��BITMAPFILEHEADER�ṹ��

��ͼ����ʾ�����������ָ�꣺


��

SetDIBitsToDevice��StretchDIBits��ʽ��Ҫ����ָ��DIB��ָ�꣬��Ϊ���������ֲ��������ļ�������ڡ���������������ʾ����������壺


��

ȷʵ����DIB�ֳ�������������Ǻ����õģ�ֻ�����Ǹ�ϲ��������DIB�����ڵ�����������packed DIB�򽻵���

����������ָ�꣬SetDIBitsToDevice��StretchDIBits��ʽͨ��Ҳ��ҪDIB��ͼ�ؿ��Ⱥ͸߶ȡ���ֻ����ʾDIB��һ���֣��Ͳ�����ȷ��֪����Щֵ�������ǻᶨ������DIBͼ��λԪ�����ڶ���ľ��ε����ޡ�

��Ե�ͼ����ʾ
��

SetDIBitsToDevice��ʽ��ʾû���������С��DIB��DIB��ÿ��ͼ�ض�Ӧ������豸��һ��ͼ���ϣ�����DIB�е�ͼ��һ���ᱻ��ȷ��ʾ������Ҳ����˵��ͼ��Ķ������Ϸ����κλ�Ӱ��װ�����ݵ�����ת����Ӱ������ʾDIB�Ŀ�ʼλ�ã�����Ӱ����ʾ������ͼƬ��С�ͷ��򡣸ú�ʽ���£�

iLines = 	SetDIBitsToDevice (
               			hdc,           	// device context handle
               			xDst,          	// x destination coordinate
              		 	yDst,          	// y destination coordinate
               			cxSrc,         	// source rectangle width
               			cySrc,         	// source rectangle height
               			xSrc,          	// x source coordinate
               			ySrc,          	// y source coordinate
               			yScan,         	// first scan line to draw
               			cyScans,       	// number of scan lines to draw
               			pBits,         	// pointer to DIB pixel bits
               			pInfo,         	// pointer to DIB information
               			fClrUse) ;     	// color use flag

��Ҫ�Բ����������е��ᷳ���ڶ�������£���ʽ�������ȿ�����Ҫ�򵥡�������������;����˵�������÷���������߰��㣬�������ǽ�ѧ����ô������

��GDI��ʾ��ʽһ����SetDIBitsToDevice�ĵ�һ��������װ�����ݴ��ţ���ָ����ʾDIB���豸��������������xDst��yDst��������豸���߼����꣬��ָ������ʾDIBͼ�����Ͻǵ����꣨���϶ˡ�ָ�����Ӿ��ϵ��Ϸ���������DIBͼ�صĵ�һ�У���ע�⣬��Щ�����߼����꣬������Ǹ����ʵ���������õ��κ�����ת����ʽ����Windows NT������£��趨���κοռ�ת�������ڶ���MM_TEXTӳ�䷽ʽ�£����԰���Щ������Ϊ0������ʾƽ��������������ʾDIBͼ��

��������ʾ����DIBͼ������ʾ���е�һ���֣���������ĸ����������á�����DIBͼ�����ϵ����϶��µķ��������������⣬�������̸����Щ������Ӧ���������ʾ����DIBʱ��Ӧ��xSrc��ySrc�趨Ϊ0������cxSrc��cySrcӦ�ֱ���DIB��ͼ�ؿ��Ⱥ͸߶ȡ�ע�⣬��ΪBITMAPINFOHEADER�ṹ��biHeight��λ������϶��µ�DIB��˵�Ǹ��ģ�cySrcӦ�趨ΪbiHeight��λ�ľ���ֵ��

�˺�ʽ���ļ� ��/Platform SDK/Graphics and Multimedia Services/GDI/Bitmaps/Bitmap Reference/Bitmap Functions/SetDIBitsToDevice����˵xSrc��ySrc��cxSrc��cySrc�������߼���λ�����Dz���ȷ�ģ�������ͼ�ص�����ͳߴ硣���DIB�ڵ�ͼ�أ�ӵ���߼�����͵�λ��û��ʲô����ġ����ң�������ʲôӳ�䷽ʽ��������豸����ʾ��DIBʼ����cxSrcͼ�ؿ���cySrcͼ�ظߡ�

�����Ȳ���ϸ��������������yScan��cyScan����Щ���������Ӵ�Ƭ������ͨ�����ݻ���ȡ����ʱ��͸��ÿ����ʾDIB��һС���ּ��ٶԼ����������ͨ����yScan�趨Ϊ0��cyScan�趨ΪDIB�ĸ߶ȡ�

pBits������ָ��DIBͼ��λԪ��ָ�ꡣpInfo������ָ��DIB��BITMAPINFO�ṹ��ָ�ꡣ��ȻBITMAPINFO�ṹ��λַ��BITMAPINFOHEADER�ṹ��λַ��ͬ������SetDIBitsToDevice�ṹ������Ϊʹ��BITMAPINFO�ṹ����ʾ�������1λԪ��4λԪ��8λԪDIB������ͼ��Ѷ��ͷ��������ɫ�ʶ��ձ�������pInfo����������Ϊָ��BITMAPINFO�ṹ��ָ�꣬��Ҳ��ָ��BITMAPCOREINFO��BITMAPV4HEADER��BITMAPV5HEADER�ṹ��ָ�ꡣ

����һ��������DIB_RGB_COLORS��DIB_PAL_COLORS����WINGDI.H�ڷֱ���Ϊ0��1�������ʹ��DIB_RGB_COLORS������ζ��DIB������ɫ�ʶ��ձ���DIB_PAL_COLORS���ָ����DIB�ڵ�ɫ�ʶ��ձ��Ѿ���ָ����װ��������ѡ����ʶ��ĵ�ɫ�̵�16λԪ�������档����һ�����ǽ�ѧϰ���ѡ�������ʹ��DIB_RGB_COLORS��������0��

SetDIBitsToDevice��ʽ��������ʾ��ɨ���е���Ŀ��

��ˣ�Ҫ����SetDIBitsToDevice����ʾ����DIBͼ������Ҫ������Ѷ��

  •  hdc Ä¿ï¿½Ä±ï¿½ï¿½ï¿½ï¿½×°ï¿½ï¿½ï¿½ï¿½ï¿½Ý´ï¿½ï¿½ï¿½
    ��
  •  xDst��yDst Í¼ï¿½ï¿½ï¿½ï¿½ï¿½Ï½Çµï¿½Ä¿ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½
    ��
  •  cxDib��cyDib DIB��ͼ�ؿ��Ⱥ͸߶ȣ������cyDib��BITMAPINFOHEADER�ṹ��biHeight��λ�ľ���ֵ��
    ��
  •  pInfo��pBits Ö¸ï¿½ï¿½ï¿½ï¿½ï¿½Í¼ï¿½ï¿½Ñ¶ï¿½ï¿½ï¿½Öºï¿½Í¼ï¿½ï¿½Î»Ôªï¿½ï¿½Ö¸ï¿½ï¿½
    ��

Ȼ�������з�������SetDIBitsToDevice��

SetDIBitsToDevice (
     	hdc,      	// device context handle
     	xDst,     	// x destination coordinate
    	yDst,     	// y destination coordinate
     	cxDib,  	// source rectangle width
     	cyDib,  	// source rectangle height
    	0,        	// x source coordinate
    	0,        	// y source coordinate
     	0,        	// first scan line to draw
    	cyDib,  	// number of scan lines to draw
    	pBits,   	// pointer to DIB pixel bits
    	pInfo,	    // pointer to DIB information
     	0) ;      	// color use flag

��ˣ���DIB��12�������У��ĸ��趨Ϊ0��һ�����ظ��ġ�

��ʽ15-2 SHOWDIB1ͨ��ʹ��SetDIBitsToDevice��ʽ��ʾDIB��

 ï¿½ï¿½Ê½15-2  SHOWDIB1
SHOWDIB1.C
/*---------------------------------------------------------------------
   	SHOWDIB1.C -- 		Shows a DIB in the client area
                 			(c) Charles Petzold, 1998
---------------------------------------------------------------------*/

#include <windows.h>
#include "dibfile.h"
#include "resource.h"

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
TCHAR szAppName[] = TEXT ("ShowDib1") ;
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, TEXT ("Show DIB #1"),
                            WS_OVERLAPPEDWINDOW,
                          	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 ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
{
     	static 	BITMAPFILEHEADER 	* pbmfh ;
     	static 	BITMAPINFO       	* pbmi ;
     	static 	BYTE             	* pBits ;
     	static 	int                	cxClient, cyClient, cxDib, cyDib ;
     	static 		TCHAR           szFileName [MAX_PATH], szTitleName [MAX_PATH] ;
     	BOOL                      bSuccess ;
     	HDC                       	hdc ;
     	PAINTSTRUCT               	ps ;

     	switch (message)
     	{
     	case 	WM_CREATE:
          			DibFileInitialize (hwnd) ;
          			return 0 ;

     	case 	WM_SIZE:
          			cxClient = LOWORD (lParam) ;
          			cyClient = HIWORD (lParam) ;
          			return 0 ;

     	case 	WM_INITMENUPOPUP:
          			EnableMenuItem ((HMENU) wParam, IDM_FILE_SAVE,   
                    pbmfh ? MF_ENABLED : MF_GRAYED) ;
          			return 0 ;

     	case 	WM_COMMAND:
          			switch (LOWORD (wParam))
          			{
          			case 	IDM_FILE_OPEN:
                    			// Show the File Open dialog box

               					if (!DibFileOpenDlg (hwnd, szFileName, szTitleName))
                    					return 0 ;
               
                    			// If there's an existing DIB, free the memory

               					if (pbmfh)
               					{
                    					free (pbmfh) ;
						pbmfh = NULL ;
               				}
                    					// Load the entire DIB into memory

               				SetCursor (LoadCursor (NULL, IDC_WAIT)) ;
               				ShowCursor (TRUE) ;

               				pbmfh = DibLoadImage (szFileName) ;
               				ShowCursor (FALSE) ;
               				SetCursor (LoadCursor (NULL, IDC_ARROW)) ;

                    		// Invalidate the client area for later update

               				InvalidateRect (hwnd, NULL, TRUE) ;

               				if (pbmfh == NULL)
              				{
                MessageBox (	hwnd, TEXT ("Cannot load DIB file"), 
						szAppName, 0) ;
                    				return 0 ;
               				}
                    	    // Get pointers to the info structure & the bits

               				pbmi  	= (BITMAPINFO *) (pbmfh + 1) ;
               				pBits 	= (BYTE *) pbmfh + pbmfh->bfOffBits ;

                    				// Get the DIB width and height

               	  if (pbmi->bmiHeader.biSize == sizeof (BITMAPCOREHEADER))
              				{
                       cxDib	= ((BITMAPCOREHEADER *) pbmi)->bcWidth ;
                       cyDib	= ((BITMAPCOREHEADER *) pbmi)->bcHeight ;
               				}
               				else
           				{
                    	cxDib	= 	pbmi->bmiHeader.biWidth ;
                    	cyDib 	= abs(	pbmi->bmiHeader.biHeight) ;
               				}
               				return 0 ;

          				case 	IDM_FILE_SAVE:
                    	// Show the File Save dialog box

               			if (!DibFileSaveDlg (hwnd, szFileName, szTitleName))
                    				return 0 ;
               
                    				// Save the DIB to memory

               				SetCursor (LoadCursor (NULL, IDC_WAIT)) ;
               				ShowCursor (TRUE) ;

               				bSuccess = DibSaveImage (szFileName, pbmfh) ;
               				ShowCursor (FALSE) ;
               				SetCursor (LoadCursor (NULL, IDC_ARROW)) ;

               				if (!bSuccess)
                   MessageBox (	hwnd, TEXT ("Cannot save DIB file"), 
                                szAppName, 0) ;
               			return 0 ;
          		}
          		break ;

     	case 	WM_PAINT:
          			hdc = BeginPaint (hwnd, &ps) ;

          			if (pbmfh)
               	SetDIBitsToDevice (hdc, 
                                   0,         		// xDst
                                   0,         		// yDst
                                   cxDib,           	// cxSrc
                                   cyDib,           	// cySrc
                                   0,         		// xSrc
                                   0,         		// ySrc
                                   0,         		// first scan line
                                   cyDib,           	// number of scan lines
                                   pBits, 
                                   pbmi, 
                                   DIB_RGB_COLORS) ;
          			EndPaint (hwnd, &ps) ;
          			return 0 ;
          
     	case 	WM_DESTROY:
          			if (pbmfh)
               				free (pbmfh) ;

          			PostQuitMessage (0) ;
          			return 0 ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}
 DIBFILE.H
/*-------------------------------------------------------------------------
   	DIBFILE.H -- Header File for DIBFILE.C
  -----------------------------------------------------------------------*/
void DibFileInitialize (HWND hwnd) ;
BOOL DibFileOpenDlg	(HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName) ;
BOOL DibFileSaveDlg	(HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName) ;

BITMAPFILEHEADER * 	DibLoadImage 	(PTSTR pstrFileName) ;
BOOL             DibSaveImage(PTSTR pstrFileName, BITMAPFILEHEADER *) ;
 DIBFILE.C
/*---------------------------------------------------------------------------
   	DIBFILE.C -- DIB File Functions
----------------------------------------------------------------------------*/

#include <windows.h>
#include <commdlg.h>
#include "dibfile.h"

static OPENFILENAME ofn ;
void DibFileInitialize (HWND hwnd)
{
     	static TCHAR szFilter[] = TEXT ("Bitmap Files (*.BMP)\0*.bmp\0") \
                TEXT ("All Files (*.*)\0*.*\0\0") ;
     	ofn.lStructSize       		= sizeof (OPENFILENAME) ;
     	ofn.hwndOwner         	= hwnd ;
     	ofn.hInstance         		= NULL ;
     	ofn.lpstrFilter       		= szFilter ;
     	ofn.lpstrCustomFilter 	= NULL ;
     	ofn.nMaxCustFilter    	= 0 ;
     	ofn.nFilterIndex      	= 0 ;
     	ofn.lpstrFile         	= NULL ;  // Set in Open and Close functions
     	ofn.nMaxFile    		= MAX_PATH ;
     	ofn.lpstrFileTitle    	= NULL ;   // Set in Open and Close functions
     	ofn.nMaxFileTitle     		= MAX_PATH ;
     	ofn.lpstrInitialDir   		= NULL ;
     	ofn.lpstrTitle        		= NULL ;
     	ofn.Flags             		= 0 ;       // Set in Open and Close functions
     	ofn.nFileOffset       		= 0 ;
     	ofn.nFileExtension    		= 0 ;
     	ofn.lpstrDefExt       		= TEXT ("bmp") ;
     	ofn.lCustData         		= 0 ;
     	ofn.lpfnHook          		= NULL ;
	ofn.lpTemplateName 	 = NULL ;
}
BOOL DibFileOpenDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName)
{
     	ofn.hwndOwner         	= hwnd ;
     	ofn.lpstrFile         		= pstrFileName ;
     	ofn.lpstrFileTitle    		= pstrTitleName ;
     	ofn.Flags             		= 0 ;
     
     	return GetOpenFileName (&ofn) ;
}

BOOL DibFileSaveDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName)
{
     	ofn.hwndOwner         	= hwnd ;
     	ofn.lpstrFile         		= pstrFileName ;
     	ofn.lpstrFileTitle    		= pstrTitleName ;
     	ofn.Flags             		= OFN_OVERWRITEPROMPT ;
     
     	return GetSaveFileName (&ofn) ;
}

BITMAPFILEHEADER * DibLoadImage (PTSTR pstrFileName)
{
     	BOOL               		bSuccess ;
     	DWORD              		dwFileSize, dwHighSize, dwBytesRead ;
     	HANDLE             		hFile ;
     	BITMAPFILEHEADER * 	pbmfh ;

     	hFile = CreateFile (	pstrFileName, GENERIC_READ, FILE_SHARE_READ,NULL,
        OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN,NULL) ;

     	if 	(	hFile == INVALID_HANDLE_VALUE)
          			return NULL ;

     	dwFileSize = GetFileSize (hFile, &dwHighSize) ;

     	if (dwHighSize)
     	{
          			CloseHandle (hFile) ;
          			return NULL ;
     	}

     	pbmfh = malloc (dwFileSize) ;
     	if 		(!pbmfh)
     	{
          			CloseHandle (hFile) ;
          			return NULL ;
     }

     	bSuccess = ReadFile (hFile, pbmfh, dwFileSize, &dwBytesRead, NULL) ;
     	CloseHandle (hFile) ;

     	if (!bSuccess 	|| (dwBytesRead != dwFileSize)         
                   		|| (pbmfh->bfType != * (WORD *) "BM") 
                   		|| (pbmfh->bfSize != dwFileSize))
   	{
          			free (pbmfh) ;
          			return NULL ;
     	}
	return pbmfh ;
}

BOOL DibSaveImage (PTSTR pstrFileName, BITMAPFILEHEADER * pbmfh)
{
	BOOL   		bSuccess ;
	DWORD  	dwBytesWritten ;
	HANDLE 	hFile ;

	hFile = CreateFile (	pstrFileName, GENERIC_WRITE, 0, NULL,
    CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) ;

	if (hFile == INVALID_HANDLE_VALUE)
          			return FALSE ;
     	bSuccess = WriteFile (hFile, pbmfh, pbmfh->bfSize, &dwBytesWritten, NULL) ;
     	CloseHandle (hFile) ;

     	if (!bSuccess || (dwBytesWritten != pbmfh->bfSize))
     	{
          		DeleteFile (pstrFileName) ;
          		return FALSE ;
     }
     	return TRUE ;
}
 SHOWDIB1.RC ��ժ¼��
//Microsoft Developer Studio generated resource script.
#include "resource.h"
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
// Menu
SHOWDIB1 MENU DISCARDABLE 
BEGIN
	POPUP "&File"
	BEGIN
		MENUITEM "&Open...", IDM_FILE_OPEN
		MENUITEM "&Save...", IDM_FILE_SAVE
    	END
END
 RESOURCE.H ��ժ¼��
// Microsoft Developer Studio generated include file.
// Used by ShowDib1.rc

#define IDM_FILE_OPEN         40001
#define IDM_FILE_SAVE         40002

DIBFILE.C������������ʾ��File Open���͡�File Save���Ի�����ij�ʽ���Լ�������DIB������ӵ��BITMAPFILEHEADER�ṹ�����뵥���������ij�ʽ����ʽҲ�Ὣ����һ����������д����������

����SHOWDIB1.C��ִ�С�File Open����������DIB�����ᣬ��ʽ������������BITMAPINFOHEADER�ṹ��ͼ��λԪ��ƫ��������ʽҲ���DIB��ͼ�ؿ��Ⱥ͸߶ȡ�������Ѷ�������ھ�̬�����С��ڴ���WM_PAINTѶϢ�����ڼ䣬��ʽͨ������SetDIBitsToDevice��ʾDIB��

��Ȼ��SHOWDIB1��ȱ��һЩ���ܡ����磬���DIB����ʾ������˵̫����û�о����п������ƶ��鿴������һ�µ�ĩβ���޸���Щȱ�ݡ�

DIB�ĵߵ�����
��

���ǽ��õ�һ����Ҫ�Ľ�ѵ������������������Ҫ����������ҵϵͳ��Ӧ�ó�ʽ����������Ҳ��Ҫ�������ѵ�ǣ���ˮ���ա�

�ص�OS/2 Presentation Manager�����¶��ϵ�DIBͼ��λԪ�Ķ��崦�������Ķ������е�����ģ���ΪPM�ڵ��κ�����ϵ����һ���ڶ������½�ԭ�㡣���磺��PM�Ӵ��ڣ��ڶ��ģ�0,0��ԭ�����Ӵ������½ǡ��������������ܹŹ֣��ܶ��˺����ĸо�һ��������������ùŹ֣�����������λ��ѧ�ҡ�������ͼ�Ļ��ƺ�ʽҲ�������½�ָ��Ŀ�ĵء�

��ˣ���OS/2�����������ͼָ����Ŀ������(0,0)����ͼ�񽫴��Ӵ������½�����������ʾ����ͼ15-1��ʾ��


��

ͼ15-1 ��OS/2���ԣ�0��0��ΪĿ�ĵ���ʾ�ĵ���ͼ

�ڹ����Ļ����ϣ�����ʵ�ʿ����������¶��ϻ��Ƶ���ͼ��

����OS/2����ϵͳ�ԵúܹŹ֣��������ŵ��Ǹ߶ȵ�һ�¡�����ͼ�� (0,0)ԭ���ǵ���ͼ�����е�һ�еĵ�һ��ͼ�أ����Ҵ�ͼ�ر�ӳ�䵽�ڵ���ͼ���ƺ�ʽ��ָ����Ŀ�������ϡ�

Windows���ڵ������Dz��ܱ����ڲ���һ���ԡ�����ֻҪ��ʾ����DIBͼ���е�һС�����ʱ����Ҫʹ�ò���xSrc��ySrc��cxSrc��cySrc����Щ��Դ����ʹ�С��DIB���ϵĵ�һ�У�ͼ�������һ�У���ء��ⷽ����OS/2���ƣ���OS/2��ͬ���ǣ�Windows��Ŀ����������ʾͼ��Ķ��С���ˣ������ʾ����DIBͼ����ʾ�ڣ�xDst,yDst����ͼ����λ����꣨0,cyDib - 1������ͼ�ء�DIB���ϵ�����һ�о���ͼ�εĶ��С��������ʾͼ���һ���֣����ڣ�xDst,yDst����ʾ��ͼ����λ����꣨xSrc, ySrc + cySrc - 1������DIBͼ�ء�

ͼ15-2��ʾ��ͼ���������������ⷽ������ݡ������԰�������ʾ��DIB�����Ǵ����ڼ������еģ�����˵�����µߵ��������ԭ����DIBͼ�����ϵĵ�һ��λԪ��һ�µġ�SetDIBitsToDevice��xSrc��������DIB�����Ϊ��׼������cxSrc��xSrc�ұߵ�ͼ����ȣ����ֱ�ۡ�ySrc������DIB���ϵ����У�Ҳ����ͼ��ĵײ���Ϊ��׼������cySrc�Ǵ�ySrc�����ϵ�ĩ�У�ͼ��Ķ��ˣ���ͼ��߶ȡ�


��

ͼ15-2 ����DIB�����¶��ϣ�������

���Ŀ��װ�����ݾ���ʹ��MM_TEXTӳ�䷽ʽ���ڶ�ͼ�����꣬��Դ���κ�Ŀ�ľ��ν�������֮��Ĺ�ϵ��ʾ�ڱ�15-3�С�

��15-3
��Դ���� Ŀ�ľ���
(xSrc, ySrc) (xDst, yDst + cySrc - 1)
(xSrc + cxSrc - 1, ySrc) (xDst + cxSrc - 1, yDst + cySrc - 1)
(xSrc, ySrc + cySrc - 1) (xDst, yDst)
(xSrc + cxSrc - 1, ySrc + cySrc - 1) (xDst + cxSrc - 1, yDst)

(xSrc,ySrc)��ӳ�䵽(xDst,yDst)��ʹ�ñ����Եúܻ��ҡ�������ӳ�䷽ʽ�У���(xSrc,ySrc + cySrc - 1)����ӳ�䵽�߼���(xDst,yDst)��ͼ��Ҳ��MM_TEXT����ʾ��һ����

��ĿǰΪֹ�����������˵�BITMAPINFOHEADER�ṹ��biHeight��λ����ֵʱ��������������biHeight��λ�Ǹ�ֵ����DIB���ϻ��Ժ��������϶��µķ�ʽ���С������ܻ���Ϊ����������������⣬��������������Ϊ�������ʹ��ˡ�

�����Եأ����˻���Ϊ�����DIB���µ��ã���תÿһ�У�Ȼ���biHeight�趨һ����ֵ�����������������¶��ϵ�DIBһ��������������DIB������ص��ִ��ʽ��Ͳ����޸ġ�����Ϊ����һ��������Ŀ�ģ�����������һ����ʵ����ʽ��Ҫ�޸��Դ������϶��µ�DIB�������Ͳ���ʹ��һ�����߶ȡ�

���ң��˾����Ľ����ζ�����϶��µ�DIB����Դ������DIB���ϵ�����һ����һ��ԭ�㣬��Ҳ��ͼ��ĵ��С��������������������ȫ��ͬ��λ�(0,0)ԭ���DIBͼ�ز�����pBitsָ�����õĵ�һ��ͼ�أ�Ҳ����DIB����������һ��ͼ�أ���λ�����֮�䡣

ͼ15-3��ʾ��ͼ��˵���������϶��µ�DIB��ָ�����εķ�����Ҳ���������ڵ�����������е����ӡ�


��

ͼ15-3 ָ�����϶��µ�DIB������

������Σ����������ʵ���ŵ���SetDIBitsToDevice��ʽ�IJ�����DIB���ϵķ����޹ء��������ʾ��ͬһͼ�������DIB��һ�����¶��ϣ���һ�����϶��¡���ʾ������DIB�����ڵ���˳���෴����������ʹ����ͬ�IJ�������SetDIBitsToDevice��ѡ����ʾͼ�����ͬ���֡�

���ʽ15-3 APOLLO11����ʾ��

 ï¿½ï¿½Ê½15-3  APOLLO11
APOLLO11.C
/*-------------------------------------------------------------------------
   	APOLLO11.C -- 	Program for screen captures
                 		(c) Charles Petzold, 1998
  ----------------------------------------------------------------------*/

#include <windows.h>
#include "dibfile.h"

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
TCHAR szAppName[] = TEXT ("Apollo11") ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    	PSTR szCmdLine, int iCmdShow)
{
     	HWND     		hwnd ;
     	MSG      			msg ;
     	WNDCLAS		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 ("Apollo 11"),
                          	  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 BITMAPFILEHEADER	* pbmfh [2] ;
     	static BITMAPINFO       * pbmi  [2] ;
     	static BYTE             * pBits [2] ;
     	static int              cxClient, cyClient, cxDib[2], cyDib[2] ;
     	HDC                       hdc ;
     	PAINTSTRUCT               ps ;

     	switch (message)
     	{
     	case 	WM_CREATE:
          			pbmfh[0] = DibLoadImage (TEXT ("Apollo11.bmp")) ;
          			pbmfh[1] = DibLoadImage (TEXT ("ApolloTD.bmp")) ;

          			if (pbmfh[0] == NULL || pbmfh[1] == NULL)
          			{
            MessageBox (hwnd, TEXT ("Cannot load DIB file"), 
                    	szAppName, 0) ;
               				return 0 ;
          			}
               				// Get pointers to the info structure & the bits

          			pbmi  	[0] = (BITMAPINFO *) (pbmfh[0] + 1) ;
          			pbmi  	[1] = (BITMAPINFO *) (pbmfh[1] + 1) ;
          			pBits 	[0] = (BYTE *) pbmfh[0] + pbmfh[0]->bfOffBits ;
          			pBits 	[1] = (BYTE *) pbmfh[1] + pbmfh[1]->bfOffBits ;

               		// Get the DIB width and height (assume BITMAPINFOHEADER)
               		// Note that cyDib is the absolute value of the header value!!!

          			cxDib [0] =  pbmi[0]->bmiHeader.biWidth ;
          			cxDib [1] =  pbmi[1]->bmiHeader.biWidth ;

          			cyDib [0] = abs (pbmi[0]->bmiHeader.biHeight) ;
          			cyDib [1] = abs (pbmi[1]->bmiHeader.biHeight) ;
          			return 0 ;

     	case 	WM_SIZE:
          			cxClient = LOWORD (lParam) ;
          			cyClient = HIWORD (lParam) ;
          			return 0 ;
         
     	case 	WM_PAINT:
          			hdc = BeginPaint (hwnd, &ps) ;

               		// Bottom-up DIB full size

          			SetDIBitsToDevice (hdc, 
                    0,                   		         // xDst
                    cyClient / 4,        		        // yDst
                    cxDib[0],            		       // cxSrc
                    cyDib[0],            		      // cySrc
                    0,                   		     // xSrc
                    0,                   		    // ySrc
                    0,                   		   // first scan line
                    cyDib[0],            		  // number of scan lines
                    pBits[0], 
                    pbmi[0], 
                    DIB_RGB_COLORS) ;

               			// Bottom-up DIB partial

          		SetDIBitsToDevice (hdc, 
                240,                 			// xDst
                cyClient / 4,        			// yDst
                80,                  			// cxSrc
                166,                 			// cySrc
                80,                  			// xSrc
                60,                  			// ySrc
                0,                   			// first scan line
                cyDib[0],            			// number of scan lines
                pBits[0], 
                pbmi[0], 
                DIB_RGB_COLORS) ;

               			// Top-down DIB full size

          			SetDIBitsToDevice 	(hdc, 
                        340,                 // xDst
                        cyClient / 4,     // yDst
                        cxDib[0],        // cxSrc
                        cyDib[0],        // cySrc
                        0,                   // xSrc
                        0,                   // ySrc
                        0,                   // first scan line
                        cyDib[0],       // number of scan lines
                        pBits[0], 
                        pbmi[0], 
                        DIB_RGB_COLORS) ;

               			// Top-down DIB partial

          			SetDIBitsToDevice		(hdc, 
                    580,                 	// xDst
                    cyClient / 4,        	// yDst
                    80,                  	// cxSrc
                    166,                 	// cySrc
                    80,                  	// xSrc
                    60,                  	// ySrc
                    0,                   	// first scan line
                    cyDib[1],            	// number of scan lines
                    pBits[1], 
                    pbmi[1], 
                    DIB_RGB_COLORS) ;

          			EndPaint (hwnd, &ps) ;
          			return 0 ;
          
     	case 	WM_DESTROY:
          			if (pbmfh[0])
               					free (pbmfh[0]) ;
          			if (pbmfh[1])
               					free (pbmfh[1]) ;

          			PostQuitMessage (0) ;
          			return 0 ;
     	}
   	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

��ʽ��������ΪAPOLLO11.BMP�����¶��ϰ汾����APOLLOTD.BMP�����϶��°汾��������DIB�����Ƕ���220ͼ�ؿ���240ͼ�ظߡ�ע�⣬�ڳ�ʽ�ӱ�ͷ��Ѷ�ṹ��ȷ��DIB�Ŀ��Ⱥ͸߶�ʱ����ʹ��abs��ʽ�õ�biHeight��λ�ľ���ֵ������ȫ����С��Χ��ʾDIBʱ��������ʾ����ͼ�����࣬xSrc��ySrc��cxSrc��cySrc���궼����ͬ�ġ������ͼ15-4��ʾ��


��

ͼ15-4 APOLLO11��өĻ��ʾ

ע�⣬����һ��ɨ���ߡ��͡�ɨ������Ŀ���������ֲ��䣬�ҽ���������˵����pBits����Ҳ���䣬��ҪֻΪ��ʹ��ָ������Ҫ��ʾ���������ͼ����pBits��

������������ϻ�����ô��ʱ�䣬��������ΪҪ����Щ��ͼ��API������������IJ�����Э��Windows��ʽд�����ѿ��������������������Ϊ������˻���������������������������֮����������������Ϊ��������ͱ�����ˡ�

��Ҳ����������Windows�ļ��е�ijЩ�����������SetDIBitsToDevice���ļ�˵�������¶���DIB��ԭ���ǵ���ͼ�����½ǣ����϶���DIB��ԭ�������Ͻǡ����ⲻ��ģ���������Ǵ���ġ��ҿ����ø��õķ�ʽ�����������¶���DIB��ԭ���ǵ���ͼͼ������½ǣ����ǵ���ͼ���ϵĵ�һ�еĵ�һ��ͼ�ء����϶���DIB��ԭ��Ҳ�ǵ���ͼͼ������½ǣ�������������£����½��ǵ���ͼ���ϵ�����һ�еĵ�һ��ͼ�ء�

���Ҫ׫д��ȡDIB����λԪ�ĺ�ʽ��������ĸ��㡣��Ӧ������Ϊ��ʾ����DIBӳ���ָ��������һ�£��ҵĽ�������ǣ��ҽ��ڵ�ʮ���µ�DIB��ʽ����ʹ�ã���ͳһ���ַ��ο�DIBͼ�غ����꣬������ͼ����ȷ��ʾʱ��0,0��ԭ����ָ����DIBͼ���е�����ߵ�ͼ��һ����

ѭ����ʾ
��

ӵ�д�����������ȷ����ʽ�����׵�ִ�С�Ҫ��ʾ��Ƭ�����ڵ�DIB�����Է�Ϊ���������Ĺ�������DIB��������壬Ȼ����ʾ����

Ȼ������Ҳ�����ڲ����������������������������ʾDIB����ʹ���㹻��ʵ��������ṩ��DIB����DIB���������Ҳ����ʹWindows�����������ϵͳ�Ѽ������б�����Ϻͳ�ʽ���Ƶ���Ƭ�ϡ����DIB�������ʾ�������Ӽ���������������ͷdz����ᡣ

������һ�����⣺����DIBλ��������������ٴ���ý���ϣ��������ݻ������������������ɨ��������Ƶ��ȡ��ʽȡ��ͼ�����ϵ�ת����ʽ�����Ƿ�õȵ�����DIB����������������ʾ�������ǴӴ�Ƭ��绰�߻�ɨ�����ϵõ�DIBʱ���Ϳ�ʼ��ʾ����

�����Щ������SetDIBitsToDevice��ʽ��yScan��cyScans������Ŀ�ġ�Ҫʹ��������ܣ���Ҫ��κ���SetDIBitsToDevice������������ʹ��ͬ���IJ�����Ȼ�����ÿ�κ��У�pBits����ָ�����ͼͼ���������еIJ�ͬ���֡�yScans����ָ����pBitsָ��ͼ�����ϵ��У�cyScans�����DZ�pBits���õ�������������ؼ����˼���������������ҪΪ����DIB����Ѷ���֣�BITMAPINFOHEADER�ṹ��ɫ�ʶ��ձ���������һ��ͼ�����������㹻�ļ����塣

���磬����DIB��23��ͼ�أ���ϣ��ÿ�����5�еķֶ���ʾ���DIB��������������һ���ɱ���pInfo���õļ������������DIB��BITMAPINFO���֣�Ȼ��ӵ����ж�ȡ��DIB���ڼ����˽ṹ����λ�ᣬ�ܹ������һ�е�λԪ�鳤�ȡ�����5�����øô�С����һ��������飨pBits�������ڶ�ȡǰ5�У�����������ʹ�õĺ�ʽ����yScan�趨Ϊ0����cyScans�趨Ϊ5�����ڴӵ����ж�ȡ��5�У���һ�ν�yScan�趨Ϊ5��������yScan�趨Ϊ10��Ȼ��Ϊ15�����ᣬ������3�ж���pBitsָ��ļ�����飬����yScan�趨Ϊ20����cyScans�趨Ϊ3���Ժ���SetDIBitsToDevice��

������һ�����õ�ѶϢ�����ȣ�ʹ��SetDIBitsToDevice���������Ҫ���ʽ������ȡ�ú�������ʾԪ��֮���ϵ��൱���ܡ���ͨ���Dz�����ģ���Ϊ�������ڻ�����Ϻ���ʾ����֮���л������ȣ������ӻ��������򣻵ڶ���SetDIBitsToDevice��Ψһ����������ܵĵ���ͼ��ʾ��ʽ��StretchDIBits��ʽ������������ܣ����������ʹ�����Բ�ͬͼ�ش�С��ʾ������DIB�����������StretchDIBits��Σ�ÿ�θ���BITMAPINFOHEADER�ṹ�е���Ѷ������өĻ�IJ�ͬ������ʾ�����

��ʽ15-4 SEQDISPչʾ��������ܵ�ʹ�÷�����

 ï¿½ï¿½Ê½15-4  SEQDISP
SEQDISP.C
/*----------------------------------------------------------------------------
   	SEQDISP.C --	Sequential Display of DIBs
                		(c) Charles Petzold, 1998
-----------------------------------------------------------------------------*/

#include <windows.h>
#include "resource.h"

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
TCHAR szAppName[] = TEXT ("SeqDisp") ;
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, TEXT ("DIB Sequential Display"),
                        WS_OVERLAPPEDWINDOW,
                        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 ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     	static BITMAPINFO 	* 	pbmi ;
     	static BYTE       		* 	pBits ;
     	static int          			cxDib, cyDib, cBits ;
     	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") ;
     	BITMAPFILEHEADER    		bmfh ;
     	BOOL                			bSuccess, bTopDown ;
     	DWORD               			dwBytesRead ;
     	HANDLE              			hFile ;
     	HDC                 			hdc ;
     	HMENU               			hMenu ;
     	int                 			iInfoSize, iBitsSize, iRowLength, y ;
     	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_COMMAND:
          			hMenu = GetMenu (hwnd) ; 

          			switch (LOWORD (wParam))
          			{
          			case	IDM_FILE_OPEN:
                    						// Display File Open dialog
               					if (!GetOpenFileName (&ofn))
                    						return 0 ;

                    						// Get rid of old DIB

               					if (pbmi)
               					{
                    						free (pbmi) ;
                    						pbmi = NULL ;
               					}

               					if (pBits)
               					{
                    						free (pBits) ;
                    						pBits = NULL ;
               					}

                    		// Generate WM_PAINT message to erase background

               					InvalidateRect (hwnd, NULL, TRUE) ;
               					UpdateWindow (hwnd) ;

                    						// Open the file

               					hFile = CreateFile (szFileName, GENERIC_READ, 
                                FILE_SHARE_READ, NULL, OPEN_EXISTING, 
                                FILE_FLAG_SEQUENTIAL_SCAN, NULL) ;

               					if (hFile == INVALID_HANDLE_VALUE)
               					{
                   MessageBox (	hwnd, TEXT ("Cannot open file."), 
                   				szAppName, MB_ICONWARNING | MB_OK) ;
                    			return 0 ;
               					}

                    					// Read in the BITMAPFILEHEADER

				bSuccess = ReadFile (hFile,&bmfh, sizeof (BITMAPFILEHEADER),
                               &dwBytesRead, NULL) ;

               		if (!bSuccess || dwBytesRead != sizeof (BITMAPFILEHEADER))
              		{
                    MessageBox (hwnd, TEXT ("Cannot read file."), 
                                szAppName, MB_ICONWARNING | MB_OK) ;
                    			CloseHandle (hFile) ;
                    			return 0 ;
            		}

                    				// Check that it's a bitmap

               		if (bmfh.bfType != * (WORD *) "BM")
               		{
                    MessageBox (hwnd, TEXT ("File is not a bitmap."), 
                                szAppName, MB_ICONWARNING | MB_OK) ;
                    			CloseHandle (hFile) ;
                    			return 0 ;
               		}

                    			// Allocate memory for header and bits

		iInfoSize = bmfh.bfOffBits - sizeof (BITMAPFILEHEADER) ;
         		iBitsSize = bmfh.bfSize - bmfh.bfOffBits ;

               		pbmi  	= malloc (iInfoSize) ;
               		pBits 	= malloc (iBitsSize) ;

               		if (pbmi == NULL || pBits == NULL)
               				{
                    MessageBox (hwnd, TEXT ("Cannot allocate memory."), 
                                szAppName, MB_ICONWARNING | MB_OK) ;
                    			if (pbmi) 
                         		free (pbmi) ;
                    			if (pBits) 
                         		free (pBits) ;
                    			CloseHandle (hFile) ;
                    return 0 ;
               				}

                    	 // Read in the Information Header

           bSuccess = ReadFile (hFile, pbmi, iInfoSize,	&dwBytesRead, NULL) ;

               			if (!bSuccess || (int) dwBytesRead != iInfoSize)
               			{
             		 MessageBox (hwnd, TEXT ("Cannot read file."), 
                                szAppName, MB_ICONWARNING | MB_OK) ;
                    			if (pbmi) 
                         		free (pbmi) ;
                    			if (pBits) 
                         		free (pBits) ;
                    			CloseHandle (hFile) ;
                     return 0 ;
               			}

                    	// Get the DIB width and height

               			bTopDown = FALSE ;

               	   if (pbmi->bmiHeader.biSize == sizeof (BITMAPCOREHEADER))
               			{
                    cxDib = ((BITMAPCOREHEADER *) pbmi)->bcWidth ;
                    cyDib = ((BITMAPCOREHEADER *) pbmi)->bcHeight ;
                    cBits = ((BITMAPCOREHEADER *) pbmi)->bcBitCount ;
               					}
               			else
               					{
                    			if (pbmi->bmiHeader.biHeight < 0)
                         				bTopDown = TRUE ;

                    cxDib =      	 pbmi->bmiHeader.biWidth ;
                    cyDib = abs 	 (pbmi->bmiHeader.biHeight) ;
                    cBits =      	 pbmi->bmiHeader.biBitCount ;

                    if (pbmi->bmiHeader.biCompression != BI_RGB &&
                        pbmi->bmiHeader.biCompression != BI_BITFIELDS)
                    	{
                    MessageBox (hwnd, TEXT ("File is compressed."), 
                                szAppName, MB_ICONWARNING | MB_OK) ;
                         if (pbmi) 
                         free (pbmi) ;
                         if (pBits) 
                         free (pBits) ;
                         CloseHandle (hFile) ;
                     return 0 ;
                    	 }
               					}
   
                    					// Get the row length

               			iRowLength = ((cxDib * cBits + 31) & ~31) >> 3 ;

                    					// Read and display
               					SetCursor (LoadCursor (NULL, IDC_WAIT)) ;
               					ShowCursor (TRUE) ;

               					hdc = GetDC (hwnd) ;

               					for (y = 0 ; y < cyDib ; y++)
               					{
   		ReadFile (hFile, pBits + y * iRowLength,iRowLength,&dwBytesRead, NULL) ;
SetDIBitsToDevice (hdc, 
                  0,         			// xDst
                  0,         			// yDst
                  cxDib,     		// cxSrc
                  cyDib,     		// cySrc
                  0,         			// xSrc
                  0,         			// ySrc
                  bTopDown ? cyDib - y - 1 : y,
                    			// first scan line
                    1,         			// number of scan lines
                    pBits + y * iRowLength, 
                    pbmi, 
                    DIB_RGB_COLORS) ;
               		}
               		ReleaseDC (hwnd, hdc) ;
               		CloseHandle (hFile) ;
               		ShowCursor (FALSE) ;
               		SetCursor (LoadCursor (NULL, IDC_ARROW)) ;
               				return 0 ;
          			}
          			break ;

     	case 	WM_PAINT:
          			hdc = BeginPaint (hwnd, &ps) ;

          			if (pbmi && pBits)
               					SetDIBitsToDevice (hdc, 
                                0,         			// xDst
                                0,         			// yDst
                                cxDib,     			// cxSrc
                                cyDib,     			// cySrc
                                0,         			// xSrc
                                0,         			// ySrc
                                0,         			// first scan line
                                cyDib,     			// number of scan lines
                                pBits, 
                    DIB_RGB_COLORS) ;
          			EndPaint (hwnd, &ps) ;
          			return 0 ;
     
     	case 	WM_DESTROY:
          			if (pbmi)
               					free (pbmi) ;
          
          			if (pBits)
               					free (pBits) ;

          			PostQuitMessage (0) ;
          			return 0 ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}
 SEQDISP.RC ��ժ¼��
//Microsoft Developer Studio generated resource script.
#include "resource.h"
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
// Accelerator
SEQDISP ACCELERATORS DISCARDABLE 
BEGIN
	"O",     IDM_FILE_OPEN,       VIRTKEY, CONTROL, NOINVERT
END

/////////////////////////////////////////////////////////////////////////////
// Menu
SEQDISP MENU DISCARDABLE 
BEGIN
    	POPUP "&File"
    	BEGIN
        MENUITEM "&Open...\tCtrl+O",  IDM_FILE_OPEN
    	END
END
 RESOURCE.H ��ժ¼��
// Microsoft Developer Studio generated include file.
// Used by SeqDisp.rc

#define IDM_FILE_OPEN              40001

�ڴ�����File Open�����ܱ������ڼ䣬��SEQDISP.C�ڵ����е���I/O���ᷢ�����ڴ���WM_COMMAND�����ᣬ��ʽ�����ȡ����ͼ�ز���SetDIBitsToDevice��ʾ����ͼ�صĻ�Ȧ������DIB�����ڼ��������Ա��ڴ���WM_PAINT�ڼ�Ҳ����ʾ����

���ŵ����ʳߴ�
��

SetDIBitsToDevice����˽�DIB��ͼ�ضԵ���������豸����ʾ����������ӡDIB�ô�����ӡ�����Ľ�����Խ�ߣ��õ���ͼ���ԽС�������ջ�õ�����Ʊ��С��ͼ��

Ҫͨ����С��Ŵ�DIB��������豸�����ض��Ĵ�С��ʾ��������ʹ��StretchDIBits��

iLines = StretchDIBits (
               			hdc,           	// device context handle
               			xDst,          	// x destination coordinate
               			yDst,          	// y destination coordinate
               			cxDst,         	// destination rectangle width
               			cyDst,         	// destination rectangle height
               			xSrc,          	// x source coordinate
               			ySrc,          	// y source coordinate
               			cxSrc,         	// source rectangle width
               			cySrc,         	// source rectangle height
               			pBits,         	// pointer to DIB pixel bits
               			pInfo,         	// pointer to DIB information
               			fClrUse,       	// color use flag
               			dwRop) ;   	// raster operation

��ʽ�������������������棬����SetDIBitsToDevice��ͬ��

  • Ŀ����������߼�����(cxDst)�͸߶�(cyDst)���Լ���ʼ�㡣
    ��
  • ����ͨ��������ʾDIB�����ټ���������
    ��
  • ����һ��������λԪӳ�������ʽ����ָ����DIBͼ��������豸ͼ�ؽ�ϵķ�ʽ��������һ�½�ѧ����Щ���ݡ���������Ϊ�˲����趨ΪSRCCOPY��
    ��

������һ����ϸ΢�IJ������鿴SetDIBitsToDevice�����棬���ᷢ��cxSrc��cySrc��DWORD������32λԪ�������ų�������̬����StretchDIBits�У�cxSrc��cySrc���Լ�cxDst��cyDst������Ϊ�������ŵ�������̬������ζ�����ǿ���Ϊ������ʵ���ϵ�һ�¾ͻῴ��������ȷʵ��Ϊ������������Ѿ���ʼ����Ƿ��IJ���Ҳ����Ϊ����������������һ�£���������ʽ�У�xSrc��ySrc������Ϊint�������Ǵ��ģ���Щֵʼ���ǷǸ�����

DIB�ڵ���Դ���α�ӳ�䵽Ŀ�ľ��ε�������ʾ���15-4��ʾ��

��15-4
��Դ���� Ŀ�ľ���
(xSrc, ySrc) (xDst, yDst + cyDst - 1)
(xSrc + cxSrc - 1, ySrc) (xDst + cxDst - 1, yDst + cyDst - 1)
(xSrc, ySrc + cySrc - 1) (xDst, yDst)
(xSrc + cxSrc - 1, ySrc + cySrc - 1) (xDst + cxDst - 1, yDst)

�����е�-1���Dz���ȷ�ģ���Ϊ�Ŵ�ij̶ȣ��Լ�ӳ�䷽ʽ�������任���ܲ�����΢��ͬ�Ľ����

���磬����һ��2��2��DIB������StretchDIBits��xSrc��ySrc������Ϊ0��cxSrc��cySrc��Ϊ2���ٶ�������ʾ����װ�����ݾ���MM_TEXTӳ�䷽ʽ���Ҳ����б任�����xDst��yDst��Ϊ0��cxDst��cyDst��Ϊ4����ô���ǽ��Ա���2�Ŵ�DIB��ÿ����Դͼ�أ�x,y����ӳ�䵽������ʾ���ĸ�Ŀ��ͼ���ϣ�

(0,0) --> (0,2) and (1,2) and (0,3) and (1,3) 
(1,0) --> (2,2) and (3,2) and (2,3) and (3,3)
(0,1) --> (0,0) and (1,0) and (0,1) and (1,1)
(1,1) --> (2,0) and (3,0) and (2,1) and (3,1)

�ϱ���ȷ��ָ����Ŀ�ĵĽǣ�(0,3)��(3,3)��(0,0)��(3,0)������������£���������Ǹ����ֵ��

Ŀ��װ�����ݵ�ӳ�䷽ʽ��SetDIBitsToDevice��Ӱ��������xDst��yDst���߼����ꡣStretchDIBits��ȫ��ӳ�䷽ʽ��Ӱ�졣���磬������趨��yֵ���ϵ�����һ�ֶ���ӳ�䷽ʽ��DIB�ͻ�ߵ���ʾ��

������ͨ����cyDst�趨Ϊ�������ֲ����������ʵ���ϣ������Խ��κβ����Ŀ��Ⱥ͸߶ȱ�Ϊ��ֵ��ˮƽ��ֱ��תDIB����MM_TEXTӳ�䷽ʽ�£����cySrc��cyDst�����෴��DIB������ˮƽ�ᷭת���ߵ���ʾ�����cxSrc��cxDst�����෴��DIB��������ֱ�ᷭת����ʾ���ľ���ͼ��

�������ܽ���Щ���ݵ�����ʽ��xMM��yMMָ��ӳ�䷽ʽ�ķ������xֵ������������xMMֵΪ1�����xֵ������������ֵΪ-1��ͬ�������yֵ������������yMMֵΪ1�����yֵ������������ֵΪ-1��Sign��ʽ�����ֵ����TURE����춸�ֵ����FALSE��

if (!Sign (xMM �� cxSrc �� cxDst))
	DIB is flipped on its vertical axis (mirror image)
if (!Sign (yMM �� cySrc �� cyDst))
     	DIB is flipped on its horizontal axis (upside down)

�������ʣ�����ı�15-4��

��ʽ15-5 SHOWDIB��ʵ�ʳߴ���ʾDIB���Ŵ�����ʾ�����Ӵ��Ĵ�С����ӡDIB�Լ���DIB���䵽��������

 ï¿½ï¿½Ê½15-5  SHOWDIB
SHOWDIB2.C
/*--------------------------------------------------------------------------
   	SHOWDIB2.C -- 	Shows a DIB in the client area
                 		(c) Charles Petzold, 1998
---------------------------------------------------------------------------*/

#include <windows.h>
#include "dibfile.h"
#include "resource.h"

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
TCHAR szAppName[] = TEXT ("ShowDib2") ;
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, TEXT ("Show DIB #2"),
                          WS_OVERLAPPEDWINDOW,
                          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 ;
}

int ShowDib (HDC hdc, BITMAPINFO * pbmi, BYTE * pBits, int cxDib, int cyDib, 
             				int cxClient, int cyClient, WORD wShow)
{	
     	switch (wShow)
     	{
     	case 	IDM_SHOW_NORMAL:
          			return SetDIBitsToDevice (hdc, 0, 0, cxDib, cyDib, 0, 0, 
                           0, cyDib, pBits, pbmi, DIB_RGB_COLORS) ;
               
     	case 	IDM_SHOW_CENTER:
          			return SetDIBitsToDevice (hdc, (cxClient - cxDib) / 2,
                           (cyClient - cyDib) / 2, 
                    cxDib, cyDib, 0, 0, 0, cyDib, pBits, pbmi, DIB_RGB_COLORS) ;

     	case 	IDM_SHOW_STRETCH:
          			SetStretchBltMode (hdc, COLORONCOLOR) ;
return StretchDIBits(hdc,0, 0, cxClient, cyClient, 0, 0, cxDib, cyDib,
                             pBits, pbmi, DIB_RGB_COLORS, SRCCOPY) ;

     	case 	IDM_SHOW_ISOSTRETCH:
          			SetStretchBltMode (hdc, COLORONCOLOR) ;
          			SetMapMode (hdc, MM_ISOTROPIC) ;
          			SetWindowExtEx (hdc, cxDib, cyDib, NULL) ;
          			SetViewportExtEx (hdc, cxClient, cyClient, NULL) ;
          			SetWindowOrgEx (hdc, cxDib / 2, cyDib / 2, NULL) ;
          			SetViewportOrgEx (hdc, cxClient / 2, cyClient / 2, NULL) ;

return StretchDIBits(hdc,0, 0, cxDib, cyDib, 0, 0, cxDib, cyDib,
                                	     pBits, pbmi, DIB_RGB_COLORS, SRCCOPY) ;
		}
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
{
     	static BITMAPFILEHEADER 	* 	pbmfh ;
     	static BITMAPINFO       	* 	pbmi ;
     	static BYTE              	* 	pBits ;
     	static DOCINFO            	di = {sizeof (DOCINFO), 
                                   TEXT ("ShowDib2: Printing") } ;
     	static 	int                cxClient, cyClient, cxDib, cyDib ;
     	static 	PRINTDLG       	   printdlg = { sizeof (PRINTDLG) } ;
     	static 	TCHAR              szFileName [MAX_PATH], szTitleName [MAX_PATH] ;
     	static 	WORD               wShow = IDM_SHOW_NORMAL ;
     	BOOL                       bSuccess ;
     	HDC                        hdc, hdcPrn ;
     	HGLOBAL                    hGlobal ;
     	HMENU                      hMenu ;
     	int                        cxPage, cyPage, iEnable ;
     	PAINTSTRUCT                ps ;
     	BYTE                       * pGlobal ;

     	switch (message)
     	{
     	case 	WM_CREATE:
          			DibFileInitialize (hwnd) ;
          			return 0 ;

     	case 	WM_SIZE:
          			cxClient = LOWORD (lParam) ;
          			cyClient = HIWORD (lParam) ;
          			return 0 ;

     	case 	WM_INITMENUPOPUP:
          			hMenu = GetMenu (hwnd) ;

          			if (pbmfh)
               					iEnable = MF_ENABLED ;
          			else
               					iEnable = MF_GRAYED ;

          			EnableMenuItem 	(hMenu, IDM_FILE_SAVE,   	iEnable) ;
          			EnableMenuItem 	(hMenu, IDM_FILE_PRINT,  	iEnable) ;
          			EnableMenuItem 	(hMenu, IDM_EDIT_CUT,    	iEnable) ;
          			EnableMenuItem 	(hMenu, IDM_EDIT_COPY,   	iEnable) ;
          			EnableMenuItem 	(hMenu, IDM_EDIT_DELETE, iEnable) ;
          			return 0 ;

     	case 	WM_COMMAND:
          			hMenu = GetMenu (hwnd) ;

          			switch (LOWORD (wParam))
          			{
          			case	IDM_FILE_OPEN:
                    				// Show the File Open dialog box

               			if (!DibFileOpenDlg (hwnd, szFileName, szTitleName))
                    						return 0 ;
               
                    				// If there's an existing DIB, free the memory
               					if (pbmfh)
               					{
                    						free (pbmfh) ;
                    						pbmfh = NULL ;
               					}
                    				// Load the entire DIB into memory

			SetCursor (LoadCursor (NULL, IDC_WAIT)) ;
			ShowCursor (TRUE) ;

               			pbmfh = DibLoadImage (szFileName) ;

               			ShowCursor (FALSE) ;
               			SetCursor (LoadCursor (NULL, IDC_ARROW)) ;

                    		// Invalidate the client area for later update

               			InvalidateRect (hwnd, NULL, TRUE) ;

               			if (pbmfh == NULL)
               			{
                    MessageBox (	hwnd, TEXT ("Cannot load DIB file"), 
                    			szAppName, MB_ICONEXCLAMATION | MB_OK) ;
                         			return 0 ;
               			}
                    	// Get pointers to the info structure & the bits

               			pbmi	= (BITMAPINFO *) (pbmfh + 1) ;
               			pBits 	= (BYTE *) pbmfh + pbmfh->bfOffBits ;

                    	// Get the DIB width and height

               		if (pbmi->bmiHeader.biSize == sizeof (BITMAPCOREHEADER))
               			{
                    		cxDib = ((BITMAPCOREHEADER *) pbmi)->bcWidth ;
                    		cyDib = ((BITMAPCOREHEADER *) pbmi)->bcHeight ;
               			}
               				else
               			{
                    		cxDib =   	pbmi->bmiHeader.biWidth ;
                    		cyDib = abs (pbmi->bmiHeader.biHeight) ;
               			}
               				return 0 ;

          		case 	IDM_FILE_SAVE:
                    					// Show the File Save dialog box

               			if (!DibFileSaveDlg (hwnd, szFileName, szTitleName))
                    		return 0 ;
               				// Save the DIB to a disk file

               				SetCursor (LoadCursor (NULL, IDC_WAIT)) ;
               				ShowCursor (TRUE) ;

               				bSuccess = DibSaveImage (szFileName, pbmfh) ;

               				ShowCursor (FALSE) ;
               				SetCursor (LoadCursor (NULL, IDC_ARROW)) ;

               				if (!bSuccess)
                   MessageBox (	hwnd, TEXT ("Cannot save DIB file"), 
               					szAppName, MB_ICONEXCLAMATION | MB_OK) ;
               				return 0 ;

          		case 	IDM_FILE_PRINT:
               				if (!pbmfh)
                    					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 whether 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) ;

               				bSuccess = FALSE ;
                    					// Send the DIB to the printer

               				SetCursor (LoadCursor (NULL, IDC_WAIT)) ;
       				ShowCursor (TRUE) ;

     if ((StartDoc (hdcPrn, &di) > 0) && (StartPage (hdcPrn) > 0))
               				{
                    ShowDib (	hdcPrn, pbmi, pBits, cxDib, cyDib,
                          cxPage, cyPage, wShow) ;
                    
                    					if (EndPage (hdcPrn) > 0)
                    					{
                         						bSuccess = TRUE ;
                         						EndDoc (hdcPrn) ;
                    					}
               				}
               				ShowCursor (FALSE) ;
               				SetCursor (LoadCursor (NULL, IDC_ARROW)) ;

               				DeleteDC (hdcPrn) ;

               				if (!bSuccess)
               MessageBox (hwnd, TEXT ("Could not print bitmap"),
              				szAppName, MB_ICONEXCLAMATION | MB_OK) ;
               				return 0 ;

          		case 	IDM_EDIT_COPY:
          		case 	IDM_EDIT_CUT:
               				if (!pbmfh)
                    					return 0 ;

                    					// Make a copy of the packed DIB

           hGlobal = GlobalAlloc (GHND | GMEM_SHARE, pbmfh->bfSize -
                    			  sizeof (BITMAPFILEHEADER)) ;

               				pGlobal = GlobalLock (hGlobal) ;

            CopyMemory (	pGlobal, (BYTE *) pbmfh + sizeof (BITMAPFILEHEADER),
                     pbmfh->bfSize - sizeof (BITMAPFILEHEADER)) ;

               				GlobalUnlock (hGlobal) ;

                    					// Transfer it to the clipboard

               				OpenClipboard (hwnd) ;
               				EmptyClipboard () ;
               				SetClipboardData (CF_DIB, hGlobal) ;
               				CloseClipboard () ;

               				if (LOWORD (wParam) == IDM_EDIT_COPY)
                    					return 0 ;
                             // fall through if IDM_EDIT_CUT 
          		case 	IDM_EDIT_DELETE:
               				if (pbmfh)
               				{
                    				free (pbmfh) ;
                    				pbmfh = NULL ;
                    				InvalidateRect (hwnd, NULL, TRUE) ;
               				}
               				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) ;
               				InvalidateRect (hwnd, NULL, TRUE) ;
               				return 0 ;
          		}
          		break ;
         
     	case 	WM_PAINT:
          			hdc = BeginPaint (hwnd, &ps) ;

          			if (pbmfh)
               	ShowDib (	hdc, pbmi, pBits, cxDib, cyDib, 
                      cxClient, cyClient, wShow) ;

          			EndPaint (hwnd, &ps) ;
          			return 0 ;
          
     	case 	WM_DESTROY:
          			if (pbmfh)
               				free (pbmfh) ;

          			PostQuitMessage (0) ;
          			return 0 ;
     	}
  	return DefWindowProc (hwnd, message, wParam, lParam) ;
}
 SHOWDIB2.RC ��ժ¼��
//Microsoft Developer Studio generated resource script.
#include "resource.h"
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
// Menu
SHOWDIB2 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
    	END
    	POPUP "&Edit"
	BEGIN
      MENUITEM 		"Cu&t\tCtrl+X", IDM_EDIT_CUT
      MENUITEM 		"&Copy\tCtrl+C", IDM_EDIT_COPY
      MENUITEM 		"&Delete\tDelete", IDM_EDIT_DELETE
	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
END

/////////////////////////////////////////////////////////////////////////////
// Accelerator
SHOWDIB2 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
    	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 ShowDib2.rc

#define IDM_FILE_OPEN         40001
#define IDM_SHOW_NORMAL       40002
#define IDM_SHOW_CENTER       40003
#define IDM_SHOW_STRETCH      40004
#define IDM_SHOW_ISOSTRETCH   40005
#define IDM_FILE_PRINT        40006
#define IDM_EDIT_COPY         40007
#define IDM_EDIT_CUT          40008
#define IDM_EDIT_DELETE       40009
#define IDM_FILE_SAVE         40010

����˼����ShowDib��ʽ��������춹��ܱ�ѡ�������ֲ�ͬ�ķ�ʽ֮һ�ڳ�ʽ����ʾ������ʾDIB������ʹ��SetDIBitsToDevice����ʾ��������Ͻǻ�����ʾ�����������ʾDIB����ʽҲ������ʹ��StretchDIBits��ѡ�DIB�ܷŴ����������ʾ�����ڴ�����������ܻ���Σ������ܵȱ�����ʾ��Ҳ����˵������Ρ�

��DIB���Ƶ������������������干�ü�����������packed DIB�������ĸ�����������������̬ΪCF_DIB����ʽû���г��Ӽ���������DIB�ķ�������Ϊ�ڽ���ָ��packed DIB��ָ����������������Ҫ���ಽ����ȷ��ͼ��λԪ��ƫ�������ҽ�����һ�µ�ĩβʾ������������ķ�����

������ע�⵽��SHOWDIB2�е�һЩ����֮�����������256ɫ��ʾģʽִ��Windows���ͻῴ����ʾ���˵�ɫ��4λԪDIB���������ͼ�γ��ֵ����⣬����������������ɫ����ȡ��Щ��ɫ��Ҫʹ�õ�ɫ�̣�����һ�»�����Щ��������Ҳ����ע�⵽�ٶ����⣬������Windows NT��ִ��SHOWDIB2ʱ������һ��packed DIB�͵���ͼʱ���һ�չʾ�����ķ�������Ҳ��DIB��ʾ���Ӿ����У�����Ҳ����ʵ�ʳߴ�鿴���өĻ��DIB��

ɫ��ת������ɫ�̺���ʾЧ��
��

�ǵ��ڻ���С�������William Goldman����һ����Ӱ�籾��All the President's Men���У�Deep Throat����Bob Woodward�ҿ�ˮ�����ܵĹؼ��ǡ�����Ǯ�ߡ�����ô�ڵ���ͼ��ʾ�л�ø߼����ܵĹؼ����ǡ�����ͼ��λԪ�ߡ��Լ�����ɫ��ת��������ʱ����DIB��װ���޹صĸ�ʽ����Ѷ��ʾ�������弸��������ͼ�ظ�ʽ��ͬ����SetDIBitsToDevice��StretchDIBits��ʽ�����ڼ䣬ÿ��ͼ�أ������м�������������װ���޹صĸ�ʽת�����豸��ظ�ʽ��

����������£�����ת���Ǻܷ����ġ����磬��24λԪ��Ѷ��ʾ������ʾ24λԪDIB����ʾ������ʽ������л��졢�̡�����λԪ��˳����ѡ���24λԪ�豸����ʾ16λԪDIB����ҪλԪ�İ��ƺ��޼��ˡ���24λԪ�豸����ʾ4λԪ��8λԪDIBҪ����DIBɫ�ʶ��ձ��ڲ���DIBͼ��λԪ��Ȼ���λԪ���������С�

����Ҫ��4λԪ��8λԪ��Ѷ��ʾ������ʾ16λԪ��24λԪ��32λԪDIBʱ���ᷢ��ʲô�����أ�һ����ȫ��һ������ɫת�������ˡ����DIB�ڵ�ÿ��ͼ�أ�װ��������ʽ������ͼ�غ���ʾ���Ͽ��õ���ɫ֮�䡸��Ѱ��ӽ���ɫ�ʡ����������Ȧ�ͼ��㡣��GDI��ʽGetNearestColor���С���ӽ�ɫ����Ѱ������

����RGBɫ�ʵ���ά���п����������ʾ����������������֮��ľ����ǣ�


��

������������ɫ��R1G1B1��R2G2B2��ִ����ӽ�ɫ����Ѱ������һ����ɫ��������ɫ��������Ѱ��̾��롣���˵��ǣ���RGB��ɫ�������С��Ƚϡ�����ʱ��������Ҫ����ƽ�������֡�������ת����ÿ��ͼ�ر������豸��������ɫ��Ƚ��Է�����ӽ�����ɫ�����Ǹ��������൱��Ĺ�������������8λԪ�豸����ʾ8λԪDIBҲ�ý�����ӽ�ɫ����Ѱ���������ض�ÿ��ͼ�ض����У��������DIBɫ�ʶ��ձ��е�ÿ����ɫ����Ѱ�ҡ���

�����������ԭ��Ӧ�ñ���ʹ��SetDIBitsToDevice��StretchDIBits��8λԪ��Ѷ��ʾ������ʾ16λԪ��24λԪ��32λԪDIB��DIBӦת��Ϊ8λԪDIB������8λԪDDB������ø��õ���ʾЧ�ܡ�ʵ���ϣ������Ծ��ɽ�DIBת��ΪDDB��ʹ��BitBlt��StretchBlt��ʾͼ�����ӿ���ʾ�κ�DIB���ٶȡ�

�����8λԪ��Ѷ��ʾ����ִ��Windows��������л���8λԪģʽ���۲�����ʾTrue-ColorDIBʱ��Ч�ܱ仯���������ܻ�ע�⵽��һ�����⣺DIB����ʹ��������ɫ����ʾ���κ���8λԪ��Ѷ��ʾ���ϵ�DIB�պ���������20����ɫ��ʾ����λ�ö��20����ɫ�ǡ���ɫ�̹��������������⽫����һ���ᵽ��

���ᣬ�����ͬһ̨������ִ��Windows 98��Windows NT�������ܻ�ע�⵽�����ͬ������ʾģʽ��Windows NT��ʾ����DIB���ѵ�ʱ��ϳ�������Windows NT�Ŀͻ�/�ŷ�����ϵ�ṹ�Ľ������ʹ���������ڴ����API��ʽʱ�ķѸ���ʱ�䡣��������ǽ�DIBת��ΪDDB�����ҵ�һ�½�̸����CreateDIBSection��ʽ����������ر����á�

DIB��DDB�Ľ��
��

����������������ȥ����DIB�ĸ�ʽ������������DIB��ͼ��ʽ��SetDIBitsToDevice��StretchDIBits��������ֱ�Ӵ�ȡDIB�еĸ���λԪ��λԪ���ͼ�أ���һ��������һ���������Խṹ���ķ�ʽ���͸������ϵĺ�ʽ����Ҫ��ô����DIB��û�˹��ˡ�

ʵ���ϣ����Ƿ��ֻ�����һЩ���ơ�����һ�£������˽���ʹ��GDI��ʽ��DDB�ϻ���ͼ��ķ�������ĿǰΪֹ����û����DIB�ϻ�ͼ�ķ�������һ��������SetDIBitsToDevice��StretchDIBitsû��BitBlt��StretchBlt�ٶȿ죬������Windows NT�������Լ�ִ��������ӽ���ɫ��Ѱ�����磬��8λԪ��Ƶ������ʾ24λԪDIB��ʱ��

��ˣ���DIB��DDB֮�����ת�����кô��ġ����磬���������һ����Ҫ��өĻ����ʾ����ε�DIB����ô��DIBת��ΪDDB�ͺ������壬�������Ǿ��ܹ�ʹ�ÿ��ٵ�BitBlt��StretchBlt��ʽ����ʾ���ˡ�

��DIB����DDB
��

��DIB�н���GDI����ͼ��������𣿻����������Ѿ�֪���˷����������DIB�������ܹ�ʹ��CreateCompatibleBitmap��������DIB��С��ͬ������Ѷ��ʾ�����ݵ�GDI����ͼ�����Ȼ�Ὣ�õ���ͼ���ѡ�������װ�����ݲ�����SetDIBitsToDevice���Ǹ�������DC�ϻ�ͼ���������DDB������DIB��ͬ��ͼ�񣬵���������Ѷ��ʾ�����ݵ���ɫ��֯��

��Ҳ����ͨ������CreateDIBitmap�ü����������������������ʽ���﷨Ϊ��

hBitmap = CreateDIBitmap (
                   hdc,        	    // device context handle

               			       pInfoHdr,   		// pointer to DIB information header
               	   fInit,      	// 0 or CBM_INIT
               	   pBits,      	// pointer to DIB pixel bits
               	   pInfo,      	// pointer to DIB information
               	   fClrUse) ;  	// color use flag

��ע��pInfoHdr��pInfo���������������Ƿֱ���Ϊָ��BITMAPINFOHEADER�ṹ�� BITMAPINFO�ṹ��ָ�ꡣ����������֪��BITMAPINFO�ṹ���������ɫ�ʶ��ձ���BITMAPINFOHEADER�ṹ������һ����ῴ������������������á�����һ��������DIB_RGB_ COLORS�����0����DIB_PAL_COLORS��������SetDIBitsToDevice��ʽ��ʹ�á���һ���ҽ����۸����ⷽ������ݡ�

����Windows�е���ͼ��ʽ�������Ǻ���Ҫ�ġ���Ҫ����CreateDIBitmap��ʽ�����ƣ����������롸װ���޹صĵ���ͼ��������װ���޹صĹ���н������豸��صĵ���ͼ����ע��ú�ʽ����GDI����ͼ����Ĵ��ţ�CreateBitmap��CreateBitmapIndirect��CreateCompatibleBitmapҲ����һ����

����CreateDIBitmap��ʽ��򵥵ķ����ǣ�

hBitmap = CreateDIBitmap (NULL, pbmih, 0, NULL, NULL, 0) ;

Ψһ�IJ�����ָ��BITMAPINFOHEADER�ṹ������ɫ�ʶ��ձ�����ָ�ꡣ�������ʽ�У���ʽ������ɫGDI����ͼ������ڶ��ּ򵥵ķ����ǣ�

hBitmap = CreateDIBitmap (hdc, pbmih, 0, NULL, NULL, 0) ;

�������ʽ�У���ʽ��������װ���������ݵ�DDB����װ��������hdc����ָ������ĿǰΪֹ�����Ƕ���͸��CreateBitmap��������ɫ����ͼ����CreateCompatibleBitmap����������Ѷ��ʾ�����ݵĵ���ͼ�������һЩ������

��CreateDIBitmap����������ģʽ�У�ͼ�ػ�δ����ʼ�������CreateDIBitmap�ĵ�����������CBM_INIT��Windows�ͻὨ��DDB��ʹ����������������ʼ������ͼλԪ��pInfo������ָ�����ɫ�ʶ��ձ���BITMAPINFO�ṹ��ָ�ꡣpBits������ָ����BITMAPINFO�ṹָ����ɫ�ʸ�ʽ�е�λԪ���е�ָ�꣬����ɫ�ʶ��ձ���ЩλԪ��ת��Ϊ�豸����ɫ��ʽ������SetDIBitsToDevice�������ͬ��ʵ���ϣ�����CreateDIBitmap��ʽ���������г�ʽ����ʵ����

HBITMAP CreateDIBitmap (	HDC hdc, CONST BITMAPINFOHEADER * pbmih,
                        DWORD fInit, CONST VOID * pBits, 
                        CONST BITMAPINFO * pbmi, UINT fUsage)
{
     	HBITMAP 	hBitmap ;
     	HDC     		hdc ;
     	int     		cx, cy, iBitCount ;

     	if (pbmih->biSize == sizeof (BITMAPCOREHEADER))
	{
          			cx   = ((PBITMAPCOREHEADER) pbmih)->bcWidth ;
          			cy   = ((PBITMAPCOREHEADER) pbmih)->bcHeight ;
          			iBitCount 	= ((PBITMAPCOREHEADER) pbmih)->bcBitCount ;
     	}
     	else
     {
          			cx  = pbmih->biWidth ;
          			cy  = pbmih->biHeight ;
          			iBitCount 	= pbmih->biBitCount ;
     }
     	if (hdc)
          			hBitmap = CreateCompatibleBitmap (hdc, cx, cy) ;
     	else
          			hBitmap = CreateBitmap (cx, cy, 1, 1, NULL) ;
     	if 	(fInit == CBM_INIT)
     	{
           			hdcMem = CreateCompatibleDC (hdc) ;
           			SelectObject (hdcMem, hBitmap) ;
           			SetDIBitsToDevice (	hdcMem, 0, 0, cx, cy, 0, 0, 0 cy, 
                    pBits, pbmi, fUsage) ;
           			DeleteDC (hdcMem) ;
     }

return hBitmap ;
}

���������ʾDIBһ�Σ�������SetDIBitsToDevice��ʾ̫���������CreateDIBitmap��ʹ��BitBlt��StretchBlt����ʾDDB��û��ʲô���塣��ΪSetDIBitsToDevice��CreateDIBitmap��ִ����ɫת����������������ռ��ͬ������ʱ�䡣ֻ���ڶ����ʾDIBʱ�������ڴ���WM_PAINTѶϢʱ����������ת���������塣

��ʽ15-6 DIBCONVչʾ������SetDIBitsToDevice��DIB����ת��ΪDDB�ķ�����

 ï¿½ï¿½Ê½15-6  DIBCONV
DIBCONV.C
/*--------------------------------------------------------------------------
   	DIBCONV.C --	Converts a DIB to a DDB
                		(c) Charles Petzold, 1998
----------------------------------------------------------------------------*/

#include <windows.h>
#include <commdlg.h>
#include "resource.h"

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
TCHAR szAppName[] = TEXT ("DibConv") ;

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 ("DIB to DDB Conversion"),
                          	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 ;
}
HBITMAP CreateBitmapObjectFromDibFile (HDC hdc, PTSTR szFileName)
{
     	BITMAPFILEHEADER * 	pbmfh ;
     	BOOL               bSuccess ;
     	DWORD              dwFileSize, dwHighSize, dwBytesRead ;
     	HANDLE             hFile ;
     	HBITMAP            hBitmap ;

          			// 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 whole file

     	dwFileSize = GetFileSize (hFile, &dwHighSize) ;

     	if (dwHighSize)
     	{
          			CloseHandle (hFile) ;
          			return NULL ;
     	}

     	pbmfh = malloc (dwFileSize) ;

    	if (!pbmfh)
     	{
          			CloseHandle (hFile) ;
          			return NULL ;
     }

     	bSuccess = ReadFile (hFile, pbmfh, dwFileSize, &dwBytesRead, NULL) ;
     	CloseHandle (hFile) ;

          			// Verify the file
     	if (!bSuccess 		|| (dwBytesRead != dwFileSize)         
                   			|| (pbmfh->bfType != * (WORD *) "BM") 
                   			|| (pbmfh->bfSize != dwFileSize))
     {
          			free (pbmfh) ;
          			return NULL ;
     }
          			// Create the DDB 
     	hBitmap = CreateDIBitmap 	(hdc,              
                               			(BITMAPINFOHEADER *) (pbmfh + 1),
                                            CBM_INIT,
                               			 (BYTE *) pbmfh + pbmfh->bfOffBits,
                               			 (BITMAPINFO *) (pbmfh + 1),
                               		        DIB_RGB_COLORS) ;
     	free (pbmfh) ;
     	return hBitmap ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
{
     	static HBITMAP      	hBitmap ;
     	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 ;
     	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 DIB, delete it

               					if (hBitmap)
               					{
                    						DeleteObject (hBitmap) ;
                    						hBitmap = NULL ;
               					}
                    						// Create the DDB from the DIB

               					SetCursor (LoadCursor (NULL, IDC_WAIT)) ;
               					ShowCursor (TRUE) ;

               		   hdc = GetDC (hwnd) ;
               		   hBitmap = CreateBitmapObjectFromDibFile (hdc, szFileName) ;
               		   ReleaseDC (hwnd, hdc) ;

               					ShowCursor (FALSE) ;
               					SetCursor (LoadCursor (NULL, IDC_ARROW)) ;

                    	// Invalidate the client area for later update

               					InvalidateRect (hwnd, NULL, TRUE) ;
               					if (hBitmap == NULL)
               					{
                        MessageBox (hwnd, TEXT ("Cannot load DIB file"), 
                                	szAppName, MB_OK | MB_ICONEXCLAMATION) ;
               					}
               					return 0 ;
          			}
          			break ;

     		case	WM_PAINT:
          				hdc = BeginPaint (hwnd, &ps) ;

          				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_DESTROY:
          				if (hBitmap)
               				DeleteObject (hBitmap) ;

          				PostQuitMessage (0) ;
          				return 0 ;
     		}
     		return DefWindowProc (hwnd, message, wParam, lParam) ;
}
 DIBCONV.RC ��ժ¼��
//Microsoft Developer Studio generated resource script.
#include "resource.h"
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
// Menu
DIBCONV MENU DISCARDABLE 
BEGIN
 	POPUP "&File"
    	BEGIN
        		MENUITEM "&Open",  	IDM_FILE_OPEN
    	END
END
 RESOURCE.H ��ժ¼��
// Microsoft Developer Studio generated include file.
// Used by DibConv.rc

#define IDM_FILE_OPEN    40001

DIBCONV.C�������������ģ�������Ҫǰ��ĵ������ڶ������еĹ��ܱ������File Open�����Ļ�Ӧ�У�WndProc���г�ʽ��CreateBitmapObjectFromDibFile��ʽ���˺�ʽ������������������岢��ָ���������ָ�괫�ݸ�CreateDIBitmap��ʽ����ʽ���ص���ͼ�Ĵ��ţ�Ȼ�����DIB�ļ�����鱻�ͷš���WM_PAINTѶϢ�����ڼ䣬WndProc������ͼѡ�����ݵļ�����װ�����ݲ�ʹ��BitBlt������SetDIBitsToDevice������ʾ������ʾ����ͼ����ͨ��ʹ�õ���ͼ���ź��д���BITMAP�ṹ��GetObject��ʽ��ȡ�õ���ͼ�Ŀ��Ⱥ͸߶ȡ�

�ڴ�CreateDIBitmap��������ͼʱ���س�ʼ��DDBͼ��λԪ��֮�������Ժ���SetDIBits��ʼ��ͼ��λԪ���ú�ʽ���﷨���£�

iLines = SetDIBits (
               		hdc,          // device context handle
               		hBitmap,    // bitmap handle
               		yScan,      // first scan line to convert
               		cyScans,   // number of scan lines to convert
               		pBits,      	// pointer to pixel bits
               		pInfo,      	// pointer to DIB information
               		fClrUse) ;  // color use flag

��ʽʹ����BITMAPINFO�ṹ�е�ɫ�ʶ��ձ���λԪת��Ϊ�豸��صĸ�ʽ��ֻ��������һ�������趨ΪDIB_PAL_COLORSʱ������Ҫװ�����ݴ��š�

��DDB��DIB
��

��SetDIBits��ʽ���Ƶĺ�ʽ��GetDIBits��������ʹ�ô˺�ʽ��DDBת��ΪDIB��

int WINAPI GetDIBits (
               	hdc,        		// device context handle
               	hBitmap,    	// bitmap handle
               	yScan,      	// first scan line to convert
               	cyScans,    	// number of scan lines to convert
               	pBits,      		// pointer to pixel bits (out)
               	pInfo,      		// pointer to DIB information (out)
               	fClrUse) ;  	// color use flag

Ȼ�����˺�ʽ�����Ŀ��²���SetDIBits�ķ�����������һ������£����ʹ��CreateDIBitmap��SetDIBits��DIBת��ΪDDB��Ȼ��ʹ��GetDIBits��DDBת����DIB�����Ͳ���õ�ԭ����ͼ��������Ϊ��DIB��ת��Ϊ�豸��صĸ�ʽʱ����һЩ��Ѷ��ʧ�ˡ���ʧ����Ѷ����ȡ��춽���ת��ʱWindows��ִ�е���ʾģʽ��

�����ܻᷢ��û��ʹ��GetDIBits�ı�Ҫ�ԡ�����һ�£���ʲô���������ij�ʽ�����������е���ͼ���ţ���û���������ʼ��λ�ý�������ͼ�����ϣ������������Ǽ�����ΪDIB�ṩ���Զ���ת����GetDIBits��ʽ��һ���������ڲ�׽өĻ��ʾ���ݵ�����£������ʮ������BLOWUP��ʽ�����ġ��Ҳ�ʾ�������ʽ������Microsoft��վ��Knowledge Base����Q80080����һЩ��Ѷ��

DIB����
��

��ϣ�����Ѿ����豸��غ�װ���޹ص���ͼ���������������ĸ��DIB��ӵ�м���ɫ����֯�е�һ�֣�DDB�����ǵ�ɫ�Ļ�������ʵ����豸��ͬ�ĸ�ʽ��DIB��һ�������������飻DDB��GDI����ͼ������ɵ���ͼ���ű�ʾ��DIB�ܱ���ʾ��ת��ΪDDB��ת����DIB���������������װ���޹�λԪ���豸���λԪ֮���ת������

������������һ����ʽ������������Щ���򡣸ú�ʽ��32λԪWindows�汾�з�������ΪCreateDIBSection���﷨Ϊ��

hBitmap = CreateDIBSection (
                    hdc,         	// device context handle
                    pInfo,       	// pointer to DIB information
               	fClrUse,     	// color use flag
               	ppBits,      	// pointer to pointer variable
               	hSection,   	// file-mapping object handle
               	dwOffset) ; 	// offset to bits in file-mapping object

CreateDIBSection��Windows API������Ҫ�ĺ�ʽ֮һ��������ʹ�õ���ͼʱ����Ȼ�����ᷢ��������²��������⡣

�����Ǵ��������ƿ�ʼ������֪��DIB��ʲô������DIB section��������ʲô�أ�������һ�μ��CreateDIBSectionʱ�����ܻ�Ѱ�Ҹú�ʽ��DIB���鹤���ķ�ʽ��������ȷ�ģ�CreateDIBSection�����ľ��ǽ�����DIB��һ���֣�����ͼͼ��λԪ�ļ�����飩��

�������ǿ�һ�´���ֵ������GDI����ͼ����Ĵ��ţ��������ֵ�����Ǹú�ʽ���������˵IJ��֡�����ֵ�ƺ���ʾ��CreateDIBSection�ڹ�������CreateDIBitmap��ͬ����ʵ�ϣ���ֻ�����Ƶ���ȫ��ͬ��ʵ���ϣ���CreateDIBSection���صĵ���ͼ�����������ڱ��º���һ�����������е���ͼ������ʽ���صĵ���ͼ�����ڱ����ϲ�ͬ��

һ��������CreateDIBSection����ʵ���ԣ������ܾ������Ϊʲô���Ѵ���ֵ���������������Ҳ���ܵó����ۣ�CreateDIBSectionӦ�ó�֮ΪCreateDIBitmap��������ͬ��ǰ����ָ����CreateDIBitmapӦ�ó�֮ΪCreateDDBitmap��

���������Ǽ��һ����μ�CreateDIBSection������ȷ��ʹ���������ȣ���������������hSection��dwOffset���ֱ��趨ΪNULL��0���ҽ��ڱ�������������Щ�������÷����ڶ�������fColorUse�����趨ΪDIB_ PAL_COLORSʱ����ʹ��hdc���������fColorUseΪDIB_RGB_COLORS����0����hdc�������ԣ�����CreateDIBitmap��ͬ��hdc�������ȡ����DDB���ݵ��豸��ɫ�ʸ�ʽ����

��ˣ�CreateDIBSection��򵥵���ʽ����Ҫ�ڶ��͵��ĸ��������ڶ���������ָ��BITMAPINFO�ṹ��ָ�꣬������ǰ��ʹ�ù�����ϣ��ָ����ĸ�������ָ�궨���ָ�겻��ʹ��������ʵ���Ϻܼ򵥡�

����Ҫ����ÿͼ��24λԪ��384��256λԪDIB��24λԪ��ʽ����Ҫɫ�ʶ��ձ������������򵥵ģ��������ǿ���ΪBITMAPINFO����ʹ��BITMAPINFOHEADER�ṹ��

����Ҫ��������������BITMAPINFOHEADER�ṹ��BYTEָ��͵���ͼ���ţ�

BITMAPINFOHEADER 	bmih ;
BYTE           		* pBits ;
HBITMAP          		hBitmap ;

���ڳ�ʼ��BITMAPINFOHEADER�ṹ����λ

bmih->biSize          	= sizeof (BITMAPINFOHEADER) ;
bmih->biWidth         	= 384 ;
bmih->biHeight        	= 256 ;
bmih->biPlanes        	= 1 ;
bmih->biBitCount      	= 24 ;
bmih->biCompression   	= BI_RGB ;
bmih->biSizeImage     	= 0 ;
bmih->biXPelsPerMeter 	= 0 ;
bmih->biYPelsPerMeter 	= 0 ;
bmih->biClrUsed       	= 0 ;
bmih->biClrImportant  	= 0 ;

�ڻ���׼���ᣬ���Ǻ��иú�ʽ��

hBitmap = CreateDIBSection (NULL, (BITMAPINFO *)  &bmih, 0, &pBits, NULL, 0) ;

ע�⣬����Ϊ�ڶ�����������BITMAPINFOHEADER�ṹ��λַ�����dz����ģ���һ��BYIEָ��pBits��λַ���Ͳ������ˡ����������ĸ������Ǻ�ʽ��Ҫ��ָ��ָ���ָ�ꡣ

���Ǻ�ʽ���������ģ�CreateDIBSection���BITMAPINFOHEADER�ṹ�������㹻�ļ������������DIBͼ��λԪ���������������������Ĵ�СΪ384��256��3λԪ�顣���������ṩ��pBits�����д�����ָ��˼�������ָ�ꡣ��ʽ���ص���ͼ���ţ�������˵�ģ�����CreateDIBitmap����������ͼ������ʽ���صĴ��Ų�һ����

Ȼ�������ǻ�û�����꣬����ͼͼ����δ��ʼ���ġ�������ڶ�ȡDIB���������Լ򵥵ذ�pBits�������ݸ�ReadFile��ʽ����ȡ���ǡ����߿���ʹ��һЩ��ʽ�롸�˹����趨��

��ʽ15-7 DIBSECT���˺���CreateDIBSection������CreateDIBitmap֮�⣬��DIBCONV��ʽ���ơ�

 ï¿½ï¿½Ê½15-7  DIBSECT
DIBSECT.C
/*----------------------------------------------------------------------------
   	DIBSECT.C -- 	Displays a DIB Section in the client area
                		(c) Charles Petzold, 1998
-----------------------------------------------------------------------------*/

#include <windows.h>
#include <commdlg.h>
#include "resource.h"
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

TCHAR szAppName[] = TEXT ("DIBsect") ;
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 ("DIB Section Display"),
                          		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 ;
}
HBITMAP CreateDIBsectionFromDibFile (PTSTR szFileName)
{
     	BITMAPFILEHEADER 	                bmfh ;
     	BITMAPINFO     		 *	pbmi ;
     	BYTE           		 *	pBits ;
     	BOOL             	 bSuccess ;
     	DWORD            	 dwInfoSize, dwBytesRead ;
     	HANDLE           	hFile ;
     	HBITMAP          	hBitmap ;

          		// Open the file: read access, prohibit write access

	hFile = CreateFile (szFileName, GENERIC_READ, FILE_SHARE_READ,
                         	NULL, OPEN_EXISTING, 0, 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 BITMAPINFO structure & read it in
     	dwInfoSize = bmfh.bfOffBits - sizeof (BITMAPFILEHEADER) ;
     	pbmi = malloc (dwInfoSize) ;
     	bSuccess = ReadFile (hFile, pbmi, dwInfoSize, &dwBytesRead, NULL) ;
     	if (!bSuccess || (dwBytesRead != dwInfoSize))
     	{
          			free (pbmi) ;
          			CloseHandle (hFile) ;
          			return NULL ;
     }
          			// Create the DIB Section
     	hBitmap = CreateDIBSection (NULL, pbmi, DIB_RGB_COLORS, &pBits, NULL, 0) ;
     	if (hBitmap == NULL)
     	{
		free (pbmi) ;
		CloseHandle (hFile) ;
		return NULL ;
    	 }

          			// Read in the bitmap bits
     	ReadFile (hFile, pBits, bmfh.bfSize - bmfh.bfOffBits, &dwBytesRead, NULL) ;
     	free (pbmi) ;
     	CloseHandle (hFile) ;

     	return hBitmap ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
{
     	static HBITMAP    		hBitmap ;
     	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 ;
     	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 bitmap, delete it

               					if 	(hBitmap)
               					{
                    						DeleteObject (hBitmap) ;
                    						hBitmap = NULL ;
               					}
                    		// Create the DIB Section from the DIB file

               					SetCursor (LoadCursor (NULL, IDC_WAIT)) ;
               					ShowCursor (TRUE) ;

               			hBitmap = CreateDIBsectionFromDibFile (szFileName) ;
               				ShowCursor (FALSE) ;
               				SetCursor (LoadCursor (NULL, IDC_ARROW)) ;

                    		// Invalidate the client area for later update

               					InvalidateRect (hwnd, NULL, TRUE) ;

               					if (hBitmap == NULL)
               					{
                   MessageBox (	hwnd, TEXT ("Cannot load DIB file"), 
                   				szAppName, MB_OK | MB_ICONEXCLAMATION) ;
               					}
               					return 0 ;
          			}
          			break ;

     	case 	WM_PAINT:
          			hdc = BeginPaint (hwnd, &ps) ;

          			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_DESTROY:
          			if (hBitmap)
               				DeleteObject (hBitmap) ;

          			PostQuitMessage (0) ;
          			return 0 ;
	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}
 DIBSECT.RC��ժ¼��
//Microsoft Developer Studio generated resource script.
#include "resource.h"
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
// Menu
DIBSECT MENU DISCARDABLE 
BEGIN
    	POPUP "&File"
    	BEGIN
        	MENUITEM "&Open", 	IDM_FILE_OPEN
    	END
END
 RESOURCE.H��ժ¼��
// Microsoft Developer Studio generated include file.
// Used by DIBsect.rc

#define IDM_FILE_OPEN          40001

ע��DIBCONV�е�CreateBitmapObjectFromDibFile��ʽ��DIBSECT�е�CreateDIbsectionFromDibFile��ʽ֮�������DIBCONV��������������Ȼ���ָ��DIB��������ָ�괫�ݸ�CreateDIBitmap��ʽ��DIBSECT���ȶ�ȡBITMAPFILEHEADER�ṹ�е���Ѷ��Ȼ��ȷ��BITMAPINFO�ṹ�Ĵ�С��Ϊ�����ü����壬���ڵڶ���ReadFile�����н�����������塣Ȼ�ᣬ��ʽ��ָ��BITMAPINFO�ṹ��ָ�����pBits��ָ�괫�ݸ�CreateDIBSection����ʽ���ص���ͼ���Ų��趨pBitsָ��ʽ��Ҫ��ȡDIBͼ��λԪ�ļ�����顣

pBitsָ��ļ�������ϵͳ���С���ͨ������DeleteObjectɾ������ͼʱ��������ᱻ�Զ��ͷš�Ȼ������ʽ�����ø�ָ��ֱ�Ӹı�DIBλԪ����Ӧ�ó�ʽ͸��API���ݴ����������ʱ��ֻҪϵͳӵ����Щ������飬��WINDOWS NT�¾Ͳ���Ӱ���ٶȡ�

��֮ǰ��˵����������Ѷ��ʾ������ʾDIBʱ��ijЩʱ�������д�װ���޹�ͼ�ص��豸���ͼ�ص�ת������ʱ��Щ��ʽת�������൱��ʱ������һ�����������ʾDIB�ķ�����

  • ��ʹ��SetDIBitsToDevice��StretchDIBits����DIBֱ����ʾ��өĻ�ϣ���ʽת����SetDIBitsToDevice��StretchDIBits�����ڼ䷢����
    ��
  • ��ʹ��CreateDIBitmap�ͣ������ǣ�SetDIBits��DIBת��ΪDDB��Ȼ��ʹ��BitBlt��StretchBlt����ʾ��ʱ������趨��CBM_INIT��꣬��ʽת����CreateDIBitmap��SetDIBits�ڼ䷢����
    ��
  • ��ʹ��CreateDIBSection����DIB���飬Ȼ��ʹ��BitBlt��StretchBlt��ʾ��ʱ����ʽת����BitBlt��StretchBlt�ĺ����ڼ䷢����
    ��

�ٶ�һ��������Щ������ȷ�����������������˼�����Ǵ�CreateDIBSection���صĵ���ͼ���Ų�ͬ���������������������ͼ���ŵ�һ���ط����˵���ͼ����ʵ����ָ�򴢴��ڼ���������ϵͳά����Ӧ�ó�ʽ�ܴ�ȡ��DIB������Ҫ��ʱ��DIB��ת��Ϊ�ض���ɫ�ʸ�ʽ��ͨ��������BitBlt��StretchBlt��ʾ����ͼʱ��

��Ҳ���Խ�����ͼ����ѡ�������װ�����ݲ�ʹ��GDI��ʽ�����ơ��� pBits ����ָ���DIBͼ���ڽ���ӳ���������ΪWindows NT�µ�GDI��ʽ�������У��ڼ������豸�����ϻ���֮��͡���Ϊ���Ĵ�ȡλԪ֮ǰ�����GdiFlush��

��DIBSECT���������pBits��������Ϊ��ʽ������Ҫ��������ˡ�����ʹ��CreateDIBSection����Ҫԭ�����������Ҫֱ�Ӹ���λԪֵ����CreateDIBSection����֮���ƺ���û�б�ķ�����ȡ��λԪָ���ˡ�

DIB�������������
��

��CreateDIBitmap���صĵ���ͼ�����뺯ʽ��hdc�������õ��豸����ͬ��ƽ���ͼ��λԪ��֯������ͨ������BITMAP�ṹ��GetObject������������һ�㡣

CreateDIBSection�Ͳ�ͬ�ˡ�����Ըú�ʽ���صĵ���ͼ���ŵ�BITMAP�ṹ����GetObject�����ᷢ�ֵ���ͼ���е�ɫ����֯��BITMAPINFOHEADER�ṹ����λָ����ɫ����֯��ͬ�����ܽ��������ѡ������Ѷ��ʾ�����ݵļ�����װ�����ݡ�������һ�¹��DDB��������ì�ܣ�����Ҳ������˵��DIB�������ͼ���Ų�ͬ��ԭ��

��һ������֮���ǣ�����ܻ��ǵã�DIB��ͼ�������е�λԪ�鳤��ʼ����4�ı�����GDI����ͼ������е�λԪ�鳤�ȣ�����ʹ��GetObject��BITMAP�ṹ��bmWidthBytes��λ�еõ��ij��ȣ�ʼ����2�ı����������ÿͼ��24λԪ�Ϳ���2ͼ���趨BITMAPINFOHEADER�ṹ���������GetObject�����ͻᷢ��bmWidthBytes��λ��8������6��

ʹ�ô�CreateDIBSection���صĵ���ͼ���ţ�Ҳ����ʹ��DIBSECTION�ṹ����GetObject��

GetObject (hBitmap, sizeof (DIBSECTION), &dibsection) ;

�˺�ʽ���ܴ�����������ͼ������ʽ���صĵ���ͼ���š�DIBSECTION�ṹ�������£�

typedef struct tagDIBSECTION  // ds
{
     	BITMAP           		dsBm ;             	// BITMAP structure
     	BITMAPINFOHEADER 	dsBmih ;                  // DIB information header
     	DWORD            		dsBitfields [3] ;	// color masks
     	HANDLE           		dshSection ;       	// file-mapping object handle
     	DWORD            		dsOffset ;         	// offset to bitmap bits
}
DIBSECTION, * PDIBSECTION ;

�˽ṹ����BITMAP�ṹ��BITMAPINFOHEADER�ṹ������������λ�Ǵ��ݸ�CreateDIBSection������������������һ�½����������ǡ�

DIBSECTION�ṹ�а�������ɫ�ʶ��ձ������йص���ͼ���������ݡ�����DIB�������ͼ����ѡ�������װ������ʱ������ͨ������GetDIBColorTable���õ�ɫ�ʶ��ձ���

hdcMem = CreateCompatibleDC (NULL) ;
SelectObject (hdcMem, hBitmap) ;
GetDIBColorTable (hdcMem, uFirstIndex, uNumEntries, &rgb) ;
DeleteDC (hdcMem) ;

ͬ����������ͨ������SetDIBColorTable���趨ɫ�ʶ��ձ��е���Ŀ��

����ӳ��ѡ��
��

���ǻ�û������CreateDIBSection���������������������ǵ���ӳ������Ĵ��ź͵����е���ͼλԪ��ʼ��ƫ����������ӳ�����ʹ���ܹ��񵵰�λ춼�������һ������������Ҳ����˵������ͨ��ʹ�ü�����ָ������ȡ����������������Ҫ��������������С�

�ڴ���DIB������£��˼�����춼��ټ����������Ǻ��а����ġ�DIBͼ��λԪ�ܹ������ڴ�Ƭ�ϣ�����Ȼ���Ե���λ춼�������һ�����д�ȡ����Ȼ��Ӱ���ʽִ��Ч�ܡ������ǣ���ͼ��λԪʵ���ϴ����ڴ�Ƭ��ʱ�����Dz�������ʵ��DIB������һ���֡����DZ���λ������ĵ����ڡ�

Ϊ��չʾ�������������ʾ�ĺ�ʽ���˲���ͼ��λԪ������������⣬��DIBSECT�н���DIB����ĺ�ʽ�����ơ�Ȼ�������ṩ�˵���ӳ������ʹ��ݸ�CreateDIBSection��ʽ��ƫ������

HBITMAP CreateDIBsectionMappingFromFile (PTSTR szFileName)
{
     	BITMAPFILEHEADER 		bmfh ;
     	BITMAPINFO     			* 	pbmi ;
     	BYTE           			* 	pBits ;
     	BOOL             		bSuccess ;
     	DWORD            		dwInfoSize, dwBytesRead ;
     	HANDLE           		hFile, hFileMap ;
     	HBITMAP          		hBitmap ;

     	hFile = CreateFile (szFileName, GENERIC_READ | GENERIC_WRITE, 
                         		0,             // No sharing!
                         		NULL, OPEN_EXISTING, 0, NULL) ;

     	if (hFile == INVALID_HANDLE_VALUE)
          			return NULL ;
     	bSuccess = ReadFile (	hFile, &bmfh, sizeof (BITMAPFILEHEADER), 
                          		&dwBytesRead, NULL) ;

     	if (!bSuccess 	|| (dwBytesRead != sizeof (BITMAPFILEHEADER))         
                   		|| (bmfh.bfType != * (WORD *) "BM"))
     	{
          			CloseHandle (hFile) ;
          			return NULL ;
     	}
     	dwInfoSize = bmfh.bfOffBits - sizeof (BITMAPFILEHEADER) ;
     	pbmi = malloc (dwInfoSize) ;
     	bSuccess = ReadFile (hFile, pbmi, dwInfoSize, &dwBytesRead, NULL) ;

     	if (!bSuccess || (dwBytesRead != dwInfoSize))
     	{
          			free (pbmi) ;
          			CloseHandle (hFile) ;
          			return NULL ;
     	}
     	hFileMap = CreateFileMapping (hFile, NULL, PAGE_READWRITE, 0, 0, NULL) ;
     	hBitmap = CreateDIBSection (	NULL, pbmi, DIB_RGB_COLORS, &pBits,hFileMap, bmfh.bfOffBits) ;
	free (pbmi) ;
	return hBitmap ;
}

�����������ʽ���ᶯ��CreateDIBSection���ļ�ָ����dwOffset [��ʽ������һ������]������DWORD��С�ı�������������Ѷ��ͷ�Ĵ�Сʼ����4�ı�������ɫ�ʶ��ձ��Ĵ�СҲʼ����4�ı�����������ͼ������ͷȴ���ǣ�����14λԪ�顣���bmfh.bfOffBits��Զ������4�ı�����

�ܽ�
��

�������С�͵�DIB������ҪƵ���ز���ͼ��λԪ��������ʹ��SetDIBitsToDevice��StretchDIBits����ʾ���ǡ�Ȼ������춴��͵�DIB���˼�����������ʾЧ�ܵ����⣬������8λԪ��Ѷ��ʾ���Ϻ�Windows NT�����¡�

������ʹ��CreateDIBitmap��SetDIBits��DIBת��ΪDDB�����ڣ���ʾ����ͼ����ʹ�ÿ��ٵ�BitBlt��StretchBlt��ʽ�������ˡ�Ȼ����������ֱ�Ӵ�ȡ��Щ��װ���޹ص�ͼ��λԪ��

CreateDIBSection��һ���ܺõ����Է�������Windows NT��ͨ��BitBlt��StretchBltʹ�õ���ͼ���ű�ʹ��SetDIBitsToDevice��StretchDIBits����û��DDB��ȱ�ݣ���õ����õ�Ч�ܡ�����Ȼ���Դ�ȡDIBͼ��λԪ��

��һ�£������ۡ�Windows��ɫ�̹�������֮���������ͼ��̽����