?如果我们现有的图像资源是555,而显示格式是565的,那么,我们把图像资源读入时就要先进行转换,这种转换不是简单的加一个零位,而是要对应颜色位进行移位合并。具体方法如下: ?首先,我们要知道自己的图像资源的颜色格式,一般是b5g5r50(bbbbbgggggrrrrr0,riva128的存储方式)。 ?接下来,获取主表面的像素格式。用GetPixelFormat函数可以实现,当然,我们不应每读取一个图像就调用一次,用一个数组保存每一种颜色的起始像素位和跨度更好。另外,由于GetPixelFormat获得的是三种颜色的掩码,所以要自己写一个函数来根据掩码确切获得颜色的起始像素位和跨度。下面是例程:
WORD pf[3][2];//pf[0]是红色pf[0]是绿色pf[0]是蓝色 WORD GetBit(DWORD dword, int flag) { if(flag==0) { DWORD test=1; for (WORD i=0;i<32;i++) { if ( dword & test ) return i; test<<=1; } return 0; } if(flag==1) { DWORD test=1; test<<=31; for (WORD i=0;i<32;i++) { if ( dword & test ) return (WORD)(31-i); test>>=1; } return 0; } return 0; }
void GetPixelFormat() { DDPIXELFORMAT format; ZeroMemory( &format, sizeof(format) ); format.dwSize=sizeof(format); lpDDSPrimary->GetPixelFormat(&format);
pf[0][0] = GetBit( format.dwRBitMask ); WORD hiREDbit = GetBit( format.dwRBitMask,1 ); pf[0][1]=(WORD)(hiREDbit-pf[0][0]+1);
pf[1][0] = GetBit( format.dwGBitMask ); WORD hiGREENbit = GetBit( format.dwGBitMask,1 ); pf[1][1]=(WORD)(hiGREENbit-pf[1][0]+1);
pf[2][0] = GetBit( format.dwBBitMask ); WORD hiBLUEbit = GetBit( format.dwBBitMask,1 ); pf[2][1]=(WORD)(hiBLUEbit-pf[2][0]+1); }
//以下是像素格式转换,注意这里的二进制表示都是高位在后的机器表示方式
USHORT *k; t=PIC_HEIGHT*PIC_WIDTH;//图像的大小 k=(unsigned short *)obj;//obj是从文件中读到内存的图像数据的开始指针 WORD b,g,r; for(i=0;i<t;i++) { //以下逐一提取原图像像素的rgb值,这里默认原图像像素格式是b5g5r50(bbbbbgggggrrrrr0) r=g=b=*k; b=n1&31;//b,31=1111100000000000(高位在后)
//g,992=0000011111000000(由于高位在后,>>5后会得到xxxxx00000000000) g=(n2&992)>>5;
r=(n3&31744)>>10;//r,31744=0000000000111110 *k=(WORD)((b<<pf[2][0])|(g<<(pf[1][0]+pf[1][1]-5))|(r<<pf[0][0])); //之所以不用pf[1][0]而用(pf[1][0]+pf[1][1]-5),是因为我们要将原来的5位xxxxx变为6位0xxxxx而不是xxxxx0,当然,你也可以用pf[1][0]+1,因为你已知道pf[1][1]是绿色的跨度,其值是6。 k++; //下一个点 } 接下来就可以把obj指向的数据复制到表面上显示出来: DDSURFACEDESC2 desc; ZeroMemory( &desc, sizeof(desc) ); desc.dwSize = sizeof(desc); HRESULT r=surf->Lock( 0, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY, 0 ); if (r==DDERR_SURFACELOST) { surf->Restore(); return; }
BYTE*surfbits=(BYTE*)desc.lpSurface; BYTE *rc=(BYTE*)obj; int i; for(i=0;i<PIC_HEIGHT;i++) { memcpy(surfbits,rc,PIC_WIDTH*2); surfbits+=desc.lPitch;//表面跨度一般不等于图像宽度PIC_WIDTH rc+=PIC_WIDTH*2; } surf->Unlock( 0 );
|