最近正在做图像处理的程序,遇到一个问题:在对24位真彩色图像进行任意角度旋转时,自己的程序只能对256色的处理,却不能对24位真彩色的处理。自己的程序为:LONG lWidth;             //源图像的宽度
LONG lHeight;            //源图像的高度
LONG lNewWidth;          //旋转后的图像的宽度
LONG lNewHeight;         //旋转后图像的高度
LONG lLineBytes;        //图像每行的字节数
LONG lNewLineBytes;         //旋转后图像的宽度(lNewWidth',必须是4的倍数)
LPSTR lpDIBBits;         //指向源图像的指针
LPSTR lpSrc;             //指向源像素的指针
HDIB  hDIB;              //旋转后新DIB句柄
LPSTR lpDst;             //指向旋转图像对应像素的指针
LPSTR lpNewDIB;          //指向旋转图像的指针
LPSTR lpNewDIBBits;
LPBITMAPINFOHEADER lpbmi;    //指向BITMAPINFO结构的指针
LPBITMAPCOREHEADER lpbmc;    //指向BITMAPCOREINFO结构的指针
LONG i,j,i0,j0;
float fSina=1.0;
float fCosa=0.0;             //旋转角度的正弦和余弦
//原图4个角的坐标(以图像中心为坐标原点) float fSrcX1,fSrcY1,fSrcX2,fSrcY2,fSrcX3,fSrcY3,fSrcX4,fSrcY4; //旋转之后的4个角的坐标(以图像中心为原点) float fDstX1,fDstY1,fDstX2,fDstY2,fDstX3,fDstY3,fDstX4,fDstY4;
float f1,f2; lpDIBBits=FindDIBBits(lpDIB);     //找到源DIB图像像素起始位置
lWidth=DIBWidth(lpDIB);
lLineBytes=WIDTHBYTES(lWidth*8);   //计算图像每行的字节数
lHeight=DIBHeight(lpDIB);          //获取图像的高度

//计算原图的4个角的坐标
fSrcX1=(float)(-(lWidth-1)/2);
fSrcY1=(float)((lHeight-1)/2);
fSrcX2=(float)((lWidth-1)/2);
fSrcY2=(float)((lHeight-1)/2);
fSrcX3=(float)(-(lWidth-1)/2);
fSrcY3=(float)(-(lHeight-1)/2);
fSrcX4=(float)((lWidth-1)/2);
fSrcY4=(float)(-(lHeight-1)/2); //计算新图的4个角的坐标,(以图像中心为坐标原点)
fDstX1=fCosa*fSrcX1+fSina*fSrcY1;
fDstY1=-fSina*fSrcX1+fCosa*fSrcY1;
fDstX2=fCosa*fSrcX2+fSina*fSrcY2;
fDstY2=-fSina*fSrcX2+fCosa*fSrcY2;
fDstX3=fCosa*fSrcX3+fSina*fSrcY3;
fDstY3=-fSina*fSrcX3+fCosa*fSrcY3;
fDstX4=fCosa*fSrcX4+fSina*fSrcY4;
fDstY4=-fSina*fSrcX4+fCosa*fSrcY4; //计算旋转后的图像实际宽度 lNewWidth=(LONG)(max(fabs(fDstX4-fDstX1),fabs(fDstX3-fDstX2))+0.5);
//计算新图像每行的字节数
lNewLineBytes=WIDTHBYTES(lNewWidth*8); //计算旋转后的图像高度
lNewHeight=(LONG)(max(fabs(fDstY4-fDstY1),fabs(fDstY3-fDstY2))+0.5); //两个常数,这样不用以后每次都计算了
f1=(float)(-0.5*(lNewWidth-1)*fCosa-0.5*(lNewHeight-1)*fSina+0.5*(lWidth-1));
f2=(float)(0.5*(lNewWidth-1)*fSina-0.5*(lNewHeight-1)*fCosa+0.5*(lHeight-1)); //分配内存,以保存新DIB
hDIB=(HDIB)::GlobalAlloc(GHND,lNewLineBytes*lNewHeight+*(LPDWORD)lpDIB+PaletteSize(lpDIB));
if(hDIB==NULL)
{
return NULL;
} lpNewDIB=(char*)::GlobalLock((HGLOBAL)hDIB); //复制DIB信息头和调色板
memcpy(lpNewDIB,lpDIB,*(LPDWORD)lpDIB+PaletteSize(lpDIB)); //找到新DIB像素起始位置
lpNewDIBBits=FindDIBBits(lpNewDIB);
lpbmi=(LPBITMAPINFOHEADER)lpNewDIB;
lpbmc=(LPBITMAPCOREHEADER)lpNewDIB; //更新DIB中图像的高度和宽度
if(IS_WIN30_DIB(lpNewDIB))
{
//对于Windows3.0DIB
lpbmi->biWidth=lNewWidth;
lpbmi->biHeight=lNewHeight;
} else
{
//对于其他格式的DIB
lpbmc->bcWidth=(unsigned short)lNewWidth;
lpbmc->bcHeight=(unsigned short)lNewHeight;
}       for(i=0;i<lNewHeight;i++)                  //针对图像每行进行操作
      {
     for(j=0;j<lNewWidth;j++)                  //针对图像每列进行操作

   {
//指向新DIB第i行,第j个像素的指针
//注意此处宽度和高度是新DIB的宽度和高度
lpDst=(char*)lpNewDIBBits+lNewLineBytes*(lNewHeight-1-i)+j;
//该像素在源DIB中的坐标
i0=(LONG)(-((float)j)*fSina+((float)i)*fCosa+f2+0.5);
j0=(LONG)(((float)j)*fCosa+((float)i)*fSina+f1+0.5);
//判断是否在原图范围内
if((j0>=0)&&(j0<lWidth)&&(i0>=0)&&(i0<lHeight))
{
//指向原DIB第i0行,第j0个像素的指针
lpSrc=(char*)lpDIBBits+lLineBytes*(lHeight-1-i0)+j0; //复制像素
*lpDst=*lpSrc;
}
else
{
//对于原图中没有的像素,直接赋值为255
*((unsigned char*)lpDst)=255;
}
}
 
}
return hDIB;感谢高手们提供对24位真彩色的图像的处理!!

解决方案 »

  1.   

    基本区别就是这个地方,原来一个像素1个字节表示现在用三个自己表示,其他 的只要你打开彩色图像没问题就不需要改,彩色灰度都是一样的lLineBytes=(lWidth*8*3+31)/32*4;  //计算图像每行的字节数 循环内部
    lpDstB=(char*)lpNewDIBBits+lNewLineBytes*(lNewHeight-1-i)+j*3; 
    lpDstG=(char*)lpNewDIBBits+lNewLineBytes*(lNewHeight-1-i)+j*3+1; 
    lpDstR=(char*)lpNewDIBBits+lNewLineBytes*(lNewHeight-1-i)+j*3+2; lpSrcB=(char*)lpDIBBits+lLineBytes*(lHeight-1-i0)+j0*3; 
    lpSrcG=(char*)lpDIBBits+lLineBytes*(lHeight-1-i0)+j0*3+1; 
    lpSrcR=(char*)lpDIBBits+lLineBytes*(lHeight-1-i0)+j0*3+2;