i++>
{
//指向原图象倒数第i行像素起点地指针
lpSrc=(LPBYTE>lpDIBBits+lLineBytes*i。
//目标区域同样要注意上下倒置地问题
lpDst=(LPBYTE>lpDIBBits+lLineBytes*(lHeight-i-1>。
//备份一行
memcpy(lpNewDIBBits,lpDst,lLineBytes>。
//将倒数第i行像素复制到第i行
memcpy(lpDst,lpSrc,lLineBytes>。
//将第i行像素复制到第i行
memcpy(lpSrc,lpNewDIBBits,lLineBytes>。
}
}
else
{
AfxMessageBox("只支持256色和真彩色位图">。
//释放内存
LocalUnlock(h>。
LocalFree(h>。
returnfalse。
}
//释放内存
LocalUnlock(h>。
LocalFree(h>。
//返回
returnTRUE。
}
/*************************************************************************
*
*函数名称:
*
*RotateDIB(>
*
*参数:
*
*LPSTRlpDIB//指向源DIB图像指针
*
*intiAngle
*说明:
*
*该函数用来实现DIB图像地旋转.
*
************************************************************************/
HGLOBALWINAPIRotateDIB(LPSTRlpDIB,intiAngle>
{
//原图象宽度
LONGlWidth。
//原图象高度
LONGlHeight。
//旋转后图象宽度
LONGlNewWidth。
//旋转后图象高度
LONGlNewHeight。
//原图象地颜色数
WORDwNumColors。
//原图象地信息头结构指针
LPBITMAPINFOHEADERlpbmi,lpbmi0。
//指向原图象和目地图象地像素地指针
LPBYTElpSrc,lpDst。
//指向原图像像素地指针
LPBYTElpDIBBits。
//指向旋转后图像<像素)地指针
LPBYTElpNewDIBBits。
LPSTRlpNewDIB。
//旋转后新地DIB句柄
HDIBhDIB。
//循环变量
LONGi,j,i0,j0。
//原图像每行地字节数
LONGlLineBytes。
//旋转后图像每行地字节数
LONGlNewLineBytes。
//旋转角度地弧度
doublefArcAngle。
//旋转角度地正弦和余弦
floatfSin,fCos。
//旋转前图象四个角地坐标<以图象中心为坐标系原点)
floatfSrcX1,fSrcY1,fSrcX2,fSrcY2。
floatfSrcX3,fSrcY3,fSrcX4,fSrcY4。
//旋转后图象四个角地坐标<以图象中心为坐标系原点)
floatfDstX1,fDstY1,fDstX2,fDstY2。
floatfDstX3,fDstY3,fDstX4,fDstY4。
//两个中间量
floatf1,f2。
//找到图象地像素位置
lpDIBBits=(LPBYTE>:
:
FindDIBBits(lpDIB>。
//获取图象地宽度
lWidth=:
:
DIBWidth(lpDIB>。
//获取图象地高度
lHeight=:
:
DIBHeight(lpDIB>。
//获取图象地颜色数
wNumColors=:
:
DIBNumColors(lpDIB>。
//获取指向原位图信息头结构地指针
lpbmi0=(LPBITMAPINFOHEADER>lpDIB。
//计算原图像每行地字节数
lLineBytes=WIDTHBYTES(lWidth*(lpbmi0->biBitCount>>。
//将旋转角度从度转换到弧度
fArcAngle=(iAngle*PI>/180.0。
//计算旋转角度地正弦
fSin=(float>sin(fArcAngle>。
//计算旋转角度地余弦
fCos=(float>cos(fArcAngle>。
//计算原图地四个角地坐标<以图像中心为坐标系原点)
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>。
//计算新图四个角地坐标<以图像中心为坐标系原点)
fDstX1=fCos*fSrcX1+fSin*fSrcY1。
fDstY1=-fSin*fSrcX1+fCos*fSrcY1。
fDstX2=fCos*fSrcX2+fSin*fSrcY2。
fDstY2=-fSin*fSrcX2+fCos*fSrcY2。
fDstX3=fCos*fSrcX3+fSin*fSrcY3。
fDstY3=-fSin*fSrcX3+fCos*fSrcY3。
fDstX4=fCos*fSrcX4+fSin*fSrcY4。
fDstY4=-fSin*fSrcX4+fCos*fSrcY4。
//计算旋转后地图像实际宽度
lNewWidth=(LONG>(max(fabs(fDstX4-fDstX1>,
fabs(fDstX3-fDstX2>>+0.5>。
//计算旋转后地图像高度
lNewHeight=(LONG>(max(fabs(fDstY4-fDstY1>,
fabs(fDstY3-fDstY2>>+0.5>。
//计算旋转后图像每行地字节数
lNewLineBytes=WIDTHBYTES(lNewWidth*lpbmi0->biBitCount>。
//计算两个常数
f1=(float>(-0.5*(lNewWidth-1>*fCos-0.5*(lNewHeight-1>*fSin
+0.5*(lWidth-1>>。
f2=(float>(0.5*(lNewWidth-1>*fSin-0.5*(lNewHeight-1>*fCos
+0.5*(lHeight-1>>。
//暂时分配内存,以保存新图像
hDIB=(HDIB>:
:
GlobalAlloc(GHND,lNewHeight*lNewLineBytes+
*(LPDWORD>lpDIB+:
:
PaletteSize(lpDIB>>。
//分配内存失败,直接返回
if(!
hDIB>
returnNULL。
//锁定内存
lpNewDIB=(LPSTR>:
:
GlobalLock((HGLOBAL>hDIB>。
//复制DIB信息头和调色板
memcpy(lpNewDIB,lpDIB,*(LPDWORD>lpDIB+:
:
PaletteSize(lpDIB>>。
//获取图象地信息头结构地指针
lpbmi=(LPBITMAPINFOHEADER>lpNewDIB。
//更新DIB图象地高度和宽度
lpbmi->biWidth=lNewWidth。
lpbmi->biHeight=lNewHeight。
//找到新DIB像素地起始位置
lpNewDIBBits=(LPBYTE>:
:
FindDIBBits(lpNewDIB>。
//如果是256色位图
if(wNumColors==256>
{
//旋转后图像每行
for(i=0。
ii++>
{
//旋转后图象每列
for(j=0。
jj++>
{
//指向图象第i行第j个像素地指针
lpDst=(LPBYTE>lpNewDIBBits+lNewLineBytes*(lNewHeight-1-i>+j。
//计算每个像素点在原图象中地坐标
i0=(LONG>(-((float>j>*fSin+((float>i>*fCos+f2+0.5>。
j0=(LONG>(((float>j>*fCos+((float>i>*fSin+f1+0.5>。
//判断是否在源图象范围之内
if((j0>=0>&&(j0&&(i0>=0>&&(i0>
{
//指向源DIB图象第i0行,第j0个象素地指针
lpSrc=(LPBYTE>lpDIBBits+lLineBytes*(lHeight-1-i0>+j0。
//复制象素
*lpDst=*lpSrc。
}
else
{
//对于源图中没有地象素,直接赋值为255
*((LPBYTE>lpDst>=255。
}
}
}
}
//如果是24位真彩色位图
elseif(wNumColors==0>
{
//旋转后图像每行
for(i=0。
ii++>
{
//旋转后图象每列
for(j=0。
jj++>
{
//指向图象第i行第j个像素地指针
lpDst=(LPBYTE>lpNewDIBBits+lNewLineBytes*(lNewHeight-1-i>+3*j。
//计算每个像素点在原图象中地坐标
i0=(LONG>(-((float>j>*fSin+((float>i>*fCos+f2+0.5>。
j0=(LONG>(((float>j>*fCos+((float>i>*fSin+f1+0.5>。
//判断是否在源图象范围之内
if((j0>=0>&&(j0&&(i0>=0>&&(i0>
{
//指向源DIB图象第i0行,第j0个象素地指针
lpSrc=(LPBYTE>lpDIBBits+lLineBytes*(lHeight-1-i0>+3*j0。
//复制象素
memcpy(lpDst,lpSrc,3>。
}
else
{
//对于源图中没有地象素,直接赋值为255
memset(lpDst,255,3>。
}
}
}
}
else
{
AfxMessageBox("只支持256色和真彩色位图">。
//释放内存
GlobalUnlock(hDIB>。
GlobalFree(hDIB>。
returnNULL。
}
//返回
returnhDIB。
}
/*************************************************************************
*
*函数名称:
*ZoomDIB(>
*
*参数:
*LPSTRlpDIB-指向源DIB地指针
*floatfXZoomRatio-X轴方向缩放比率
*floatfYZoomRatio-Y轴方向缩放比率
*
*返回值:
*HGLOBAL-缩放成功返回新DIB句柄,否则返回NULL.
*
*说明:
*该函数用来缩放DIB图像,返回新生成DIB地句柄.
*
************************************************************************/
HGLOBALWINAPIZoomDIB(LPSTRlpDIB,floatfXZoomRatio,floatfYZoomRatio>
{
//源图像地宽度和高度
LONGlWidth。
LONGlHeight。
//缩放后图像地宽度和高度
LONGlNewWidth。
LONGlNewHeight。
WORDwNumColors。
//缩放后图像地宽度LONGlNewLineBytes。
//指向源图像地指针
LPBYTElpDIBBits。
//指向源象素地指针
LPBYTElpSrc。
//缩放后新DIB句柄
HDIBhDIB。
//指向缩放图像对应象素地指针
LPBYTElpDst。
//指向缩放图像地指针
LPSTRlpNewDIB。
LPBYTElpNewDIBBits。
//指向BITMAPINFO结构地指针LPBITMAPINFOHEADERlpbmi,lpbmi0。
//指向BITMAPCOREINFO结构地指针
LPBITMAPCOREHEADERlpbmc。
//循环变量<象素在新DIB中地坐标)
LONGi。
LONGj。
//象素在源DIB中地坐标
LONGi0。
LONGj0。
//图像每行地字节数
LONGlLineBytes。
//找到源DIB图像象素起始位置
lpDIBBits=(LPBYTE>:
:
FindDIBBits(lpDIB>。
//获取图像地宽度
lWidth=:
:
DIBWidth(lpDIB>。
//获取图像地高度
lHeight=:
:
DIBHeight(lpDIB>。
wNumColors=:
:
DIBNumColors(lpDIB>。
lpbmi0=(LPBITMAPINFOHEADER>lpDIB。
//计算图像每行地字节数
lLineBytes=WIDTHBYTES(lWidth*(lpbmi0->biBitCount>>。
//计算缩放后地图像实际宽度
//此处直接加0.5是因为强制类型转换时不四舍五入,而是直接截去小数部分
lNewWidth=(LONG>(lWidth*fXZoomRatio+0.5>。
//计算新图像每行地字节数
lNewLineBytes=WIDTHBYTES(lNewWidth*(lpbmi0->biBitCount>>。
//计算缩放后地图像高度
lNewHeight=(LONG>(lHeight*fYZoomRatio+0.5>。
//分配内存,以保存新DIB
hDIB=(HDIB>:
:
GlobalAlloc(GHND,lNewLineBytes*lNewHeight+*(LPDWORD>lpDIB+:
:
PaletteSize(lpDIB>>。
//判断是否内存分配失败
if(hDIB==NULL>
{
//分配内存失败
returnNULL。
}
//锁定内存
lpNewDIB=(LPSTR>:
:
GlobalLock((HGLOBAL>hDIB>。
//复制DIB信息头和调色板
memcpy(lpNewDIB,lpDIB,*(LPDWORD>lpDIB+:
:
PaletteSize(lpDIB>>。
//找到新DIB象素起始位置
lpNewDIBBits=(LPBYTE>:
:
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=(unsignedshort>lNewWidth。
lpbmc->bcHeight=(unsignedshort>lNewHeight。
}
if(wNumColors==256>
{
//针对图像每行进行操作
for(i=0。
ii++>
{
//针对图像每列进行操作
for(j=0。
jj++>
{
//指向新DIB第i行,第j个象素地指针
//注意此处宽度和高度是新DIB地宽度和高度
lpDst=(LPBYTE>lpNewDIBBits+lNewLineBytes*(lNewHeight-1-i>+j。
//计算该象素在源DIB中地坐标
i0=(LONG>(i/fYZoomRatio+0.5>。
j0=(LONG>(j/fXZoomRatio+0.5>。
//判断是否在源图范围内
if((j0>=0>&&(j0&&(i0>=0>&&(i0>
{
//指向源DIB第i0行,第j0个象素地指针
lpSrc=(LPBYTE>lpDIBBits+lLineBytes*(lHeight-1-i0>+j0。
//复制象素
*lpDst=*lpSrc。
}
else
{
//对于源图中没有地象素,直接赋值为255
*((LPBYTE>lpDst>=255。
}
}
}
}
elseif(wNumColors==0>
{for(i=0。
ii++>
{
//针对图像每列进行操作
for(j=0。
jj++>
{
//指向新DIB第i行,第j个象素地指针
//注意此处宽度和高度是新DIB地宽