高分求旋转DIB位图的例程 我在dialog上放了一个位图,现在要让这个位图可以饶中心实现任意角度的旋转找到不少实现旋转的函数,不过都没看懂,谁有实际做过的例子能给我一个吗?或者帮我写一段简单的,位图放在res里,可以用DIB load可以设置角度,点击按钮实现旋转就行分不够可以再加啊,多谢多谢 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 想要个实际的例子,劳烦大大们帮忙建个工程,最简单的dialog的就行贴太多的函数偶也看不懂,头晕啊,晕的不行了 那就帮我做一个吧,多谢多谢,分好说,解决了马上结帖,呵呵email是:[email protected] void RotBlt(HDC destDC, int srcx1, int srcy1, int srcx2, int srcy2,HDC srcDC , int destx1, int desty1 ,int thetaInDegrees ,DWORD mode){double theta = thetaInDegrees * (3.14159/180);//原图像原始大小int width = srcx2 - srcx1;int height = srcy2 - srcy1;//原图像中心点int centreX = int(float(srcx2 + srcx1)/2);int centreY = int(float(srcy2 + srcy1)/2);//判断出图像可以沿任意方向旋转的矩形框if(width>height)height = width;elsewidth = height;HDC memDC = CreateCompatibleDC(destDC);HBITMAP memBmp = CreateCompatibleBitmap(destDC, width, height);HBITMAP obmp = (HBITMAP) SelectObject(memDC, memBmp);//内存DC新在中心点int newCentre = int(float(width)/2);//开始旋转for(int x = srcx1; x<=srcx2; x++)for(int y = srcy1; y<=srcy2; y++){COLORREF col = GetPixel(srcDC,x,y);int newX = int((x-centreX)*sin(theta)+(y-centreY)*cos(theta));int newY = int((x-centreX)*cos(theta)-(y-centreY)*sin(theta));SetPixel(memDC , newX + newCentre, newY + newCentre, col);}//复制到目标DC上BitBlt(destDC, destx1, desty1, width, height, memDC, 0,0,mode);//释放内存SelectObject(memDC, obmp);DeleteDC(memDC);DeleteObject(memBmp);}用法:RotBlt(dc, 0,0,150,150,memDC,200,0, 45, SRCCOPY); 多谢puhuofeie(扑火飞蛾) ,多谢各位也多谢楼上的,不过我还是没看懂 :( #include "stdafx.h"#include "dibAPI.h"#include "math.h"#include "geotrans.h"//用双线性插值算法估计出象素值,对于超出图像范围的象素返回255unsigned char WINAPI Interpolation(LPSTR lpDIBBits,LONG lWidth,LONG lHeight,FLOAT x,FLOAT y){ //二次线性插值,首先f(x,0)=f(0,0)+x[f(1,0)-f(0,0)] //f(x,1)=f(0,1)+x[f(1,1)-f(0,1)] //f(x,y)=f(x,0)+y[f(x,1)-f(x,0)] LONG i1,i2; LONG j1,j2; unsigned char f1,f2,f3,f4; unsigned char f12,f34; FLOAT EXP; LONG lLineBytes; lLineBytes=WIDTHBYTES(lWidth*8); EXP=(FLOAT)0.0001; i1=(LONG)x; i2=i1+1; j1=(LONG)y; j2=j1+1; if((x<0)||(x>lWidth-1)||(y<0)||(y>lHeight-1)) { return 255; } else { if(fabs(x-lWidth+1)<=EXP) { if(fabs(y-lHeight+1)<=EXP) { f1=*((unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-j1)+i1); return f1; } else { f1=*((unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-j1)+i1); f3=*((unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-j1)+i2); return ((unsigned char) (f1+(y-j1)*(f3-f1))); } } else if(fabs(y-lHeight+1)<=EXP) { f1=*((unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-j1)+i1); f2=*((unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-j2)+i1); return ((unsigned char)(f1+(x-i1)*(f2-f1))); } else { f1=*((unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-j1)+i1); f2=*((unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-j2)+i1); f3=*((unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-j1)+i2); f4=*((unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-j2)+i2); f12=(unsigned char)(f1+(x-i1)*(f2-f1)); f34=(unsigned char)(f3+(x-i1)*(f4-f3)); return ((unsigned char)(f12+(y-j1)*(f34-f12))); } }}HGLOBAL WINAPI RotateInter(LPSTR lpDIB,int RotateAngle){ LONG Width,Height,NewWidth,NewHeight; LONG LineBytes,NewLineBytes; LPSTR lpDst,lpDIBBits; HDIB hDIB; LPBITMAPINFOHEADER lpbmi; LPBITMAPCOREHEADER lpbmc; LPSTR lpNewDIB,lpNewDIBBits; lpDIBBits=::FindDIBBits(lpDIB); Width=(LONG)::DIBWidth(lpDIB); Height=(LONG)::DIBHeight(lpDIB); LineBytes=WIDTHBYTES(Width*8); //下面以原图像的中点为原点,计算原图像的四个角点坐标 float SrcX1,SrcY1,SrcX2,SrcY2,SrcX3,SrcY3,SrcX4,SrcY4; //这是新图像的中点为原点,计算新图像的四个角点坐标 float DstX1,DstY1,DstX2,DstY2,DstX3,DstY3,DstX4,DstY4; float Rotate; //转动弧度角 float Sina,Cosa; float f1,f2; //这是程序中用到的两个中间常量 lpDIBBits=::FindDIBBits(lpDIB); Height=::DIBHeight(lpDIB); Width=::DIBWidth(lpDIB); Rotate=(float)RADIAN(RotateAngle); Sina=(float)sin((double)(RotateAngle)); Cosa=(float)cos((double)(RotateAngle));//将角度转换为弧度 //以下是常量的计算 //原图四个角的坐标 SrcX1=(float)(-(Width-1)/2); SrcY1=(float)((Height-1)/2); SrcX2=(float)((Width-1)/2); SrcY2=(float)((Height-1)/2); SrcX3=(float)(-(Width-1)/2); SrcY3=(float)(-(Height-1)/2); SrcX4=(float)((Width-1)/2); SrcY4=(float)(-(Height-1)/2); DstX1=Cosa*SrcX1+Sina*SrcY1; DstY1=-Sina*SrcX1+Cosa*SrcY1; DstX2=Cosa*SrcX2+Sina*SrcY2; DstY2=-Sina*SrcX2+Cosa*SrcY2; DstX3=Cosa*SrcX3+Sina*SrcY3; DstY3=-Sina*SrcX3+Cosa*SrcY3; DstX4=Cosa*SrcX4+Sina*SrcY4; DstY4=-Sina*SrcX4+Cosa*SrcY4; //这是旋转后新图像的高度和宽度,以此来分配新图像的内存,这里仍然用到了四舍五入法 NewHeight=(LONG)(max(fabs(DstY4-DstY1),fabs(DstY3-DstY2))+0.5); NewWidth=(LONG)(max(fabs(DstX4-DstX1),fabs(DstX3-DstX2))+0.5); NewLineBytes=WIDTHBYTES(NewWidth*8); hDIB=(HDIB)::GlobalAlloc(GHND,NewLineBytes*NewHeight+ *(LPDWORD)lpDIB+::PaletteSize(lpDIB)); if (hDIB == NULL) { return NULL; } lpNewDIB = (char * )::GlobalLock((HGLOBAL) hDIB); memcpy (lpNewDIB,lpDIB,*(LPDWORD)lpDIB+::PaletteSize(lpDIB)); //复制头信息和调色版 lpNewDIBBits= ::FindDIBBits(lpNewDIB); lpbmi = (LPBITMAPINFOHEADER)lpNewDIB; lpbmc = (LPBITMAPCOREHEADER)lpNewDIB; if (IS_WIN30_DIB(lpDIB)) { lpbmi->biWidth = NewWidth; lpbmi->biHeight = NewHeight; } else { lpbmc->bcWidth = (unsigned short) NewWidth; lpbmc->bcHeight = (unsigned short) NewHeight; } //以下进入图像的实际计算;首先计算两个常数 f1=(float) (-0.5*(NewWidth-1)*Cosa-0.5*(NewHeight-1)*Sina+ 0.5*(NewWidth-1) ); f2=(float) ( 0.5*(NewWidth-1)*Sina-0.5*(NewHeight-1)*Cosa+ 0.5*(NewHeight-1) ); //再以此填入图像的实际数据 float iDst,jDst,iSrc,jSrc; for (iDst=0;iDst<NewHeight;iDst++) for (jDst=0;jDst<NewWidth;jDst++) { lpDst=(char*)lpNewDIBBits+ NewLineBytes *(NewHeight-1-(LONG)iDst)+ (LONG)jDst; jSrc= ((float)jDst)*Cosa+((float)iDst)*Sina+f1 ; iSrc=-((float)jDst)*Sina+((float)iDst)*Cosa+f2 ; *lpDst= Interpolation(lpDIBBits,Width,Height,jSrc,iSrc); } return hDIB;} 关于MFC写的应用程序想转换成B/S框架的,在B/S框架中用什么语言开发比较好! 关于MFC分割窗口的问题 大家如何看待假唱。反正我是比较讨厌了。 怎么实现主线程的延时。 _beginthread 帮忙处理一下文件中存取结构体的问题? 推荐]全答对就是天才!!! 我想监视一个目录里面的文件及其子目录的改变,有什么方法? 如何判断一个指向窗口的指针可用? 特大喜讯:微软MSDN2000年春季版到了!!! 对话框问题 关于一个BITMAPBUTTON的一个问题 请各位大哥帮忙
#include "dibAPI.h"
#include "math.h"
#include "geotrans.h"
//用双线性插值算法估计出象素值,对于超出图像范围的象素返回255
unsigned char WINAPI Interpolation(LPSTR lpDIBBits,LONG lWidth,LONG lHeight,FLOAT x,FLOAT y)
{
//二次线性插值,首先f(x,0)=f(0,0)+x[f(1,0)-f(0,0)]
//f(x,1)=f(0,1)+x[f(1,1)-f(0,1)]
//f(x,y)=f(x,0)+y[f(x,1)-f(x,0)]
LONG i1,i2;
LONG j1,j2;
unsigned char f1,f2,f3,f4;
unsigned char f12,f34;
FLOAT EXP;
LONG lLineBytes;
lLineBytes=WIDTHBYTES(lWidth*8);
EXP=(FLOAT)0.0001;
i1=(LONG)x;
i2=i1+1;
j1=(LONG)y;
j2=j1+1;
if((x<0)||(x>lWidth-1)||(y<0)||(y>lHeight-1))
{
return 255;
}
else
{
if(fabs(x-lWidth+1)<=EXP)
{
if(fabs(y-lHeight+1)<=EXP)
{
f1=*((unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-j1)+i1);
return f1;
}
else
{
f1=*((unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-j1)+i1);
f3=*((unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-j1)+i2);
return ((unsigned char) (f1+(y-j1)*(f3-f1)));
}
}
else if(fabs(y-lHeight+1)<=EXP)
{
f1=*((unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-j1)+i1);
f2=*((unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-j2)+i1);
return ((unsigned char)(f1+(x-i1)*(f2-f1)));
}
else
{
f1=*((unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-j1)+i1);
f2=*((unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-j2)+i1);
f3=*((unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-j1)+i2);
f4=*((unsigned char*)lpDIBBits+lLineBytes*(lHeight-1-j2)+i2);
f12=(unsigned char)(f1+(x-i1)*(f2-f1));
f34=(unsigned char)(f3+(x-i1)*(f4-f3));
return ((unsigned char)(f12+(y-j1)*(f34-f12)));
}
}
}HGLOBAL WINAPI RotateInter(LPSTR lpDIB,int RotateAngle)
{
LONG Width,Height,NewWidth,NewHeight;
LONG LineBytes,NewLineBytes;
LPSTR lpDst,lpDIBBits; HDIB hDIB;
LPBITMAPINFOHEADER lpbmi;
LPBITMAPCOREHEADER lpbmc;
LPSTR lpNewDIB,lpNewDIBBits; lpDIBBits=::FindDIBBits(lpDIB);
Width=(LONG)::DIBWidth(lpDIB);
Height=(LONG)::DIBHeight(lpDIB);
LineBytes=WIDTHBYTES(Width*8); //下面以原图像的中点为原点,计算原图像的四个角点坐标
float SrcX1,SrcY1,SrcX2,SrcY2,SrcX3,SrcY3,SrcX4,SrcY4;
//这是新图像的中点为原点,计算新图像的四个角点坐标
float DstX1,DstY1,DstX2,DstY2,DstX3,DstY3,DstX4,DstY4;
float Rotate; //转动弧度角
float Sina,Cosa;
float f1,f2; //这是程序中用到的两个中间常量 lpDIBBits=::FindDIBBits(lpDIB);
Height=::DIBHeight(lpDIB);
Width=::DIBWidth(lpDIB);
Rotate=(float)RADIAN(RotateAngle);
Sina=(float)sin((double)(RotateAngle));
Cosa=(float)cos((double)(RotateAngle));//将角度转换为弧度
//以下是常量的计算
//原图四个角的坐标
SrcX1=(float)(-(Width-1)/2);
SrcY1=(float)((Height-1)/2);
SrcX2=(float)((Width-1)/2);
SrcY2=(float)((Height-1)/2);
SrcX3=(float)(-(Width-1)/2);
SrcY3=(float)(-(Height-1)/2);
SrcX4=(float)((Width-1)/2);
SrcY4=(float)(-(Height-1)/2); DstX1=Cosa*SrcX1+Sina*SrcY1;
DstY1=-Sina*SrcX1+Cosa*SrcY1;
DstX2=Cosa*SrcX2+Sina*SrcY2;
DstY2=-Sina*SrcX2+Cosa*SrcY2;
DstX3=Cosa*SrcX3+Sina*SrcY3;
DstY3=-Sina*SrcX3+Cosa*SrcY3;
DstX4=Cosa*SrcX4+Sina*SrcY4;
DstY4=-Sina*SrcX4+Cosa*SrcY4;
//这是旋转后新图像的高度和宽度,以此来分配新图像的内存,这里仍然用到了四舍五入法
NewHeight=(LONG)(max(fabs(DstY4-DstY1),fabs(DstY3-DstY2))+0.5);
NewWidth=(LONG)(max(fabs(DstX4-DstX1),fabs(DstX3-DstX2))+0.5);
NewLineBytes=WIDTHBYTES(NewWidth*8); hDIB=(HDIB)::GlobalAlloc(GHND,NewLineBytes*NewHeight+ *(LPDWORD)lpDIB+::PaletteSize(lpDIB));
if (hDIB == NULL)
{
return NULL;
}
lpNewDIB = (char * )::GlobalLock((HGLOBAL) hDIB);
memcpy (lpNewDIB,lpDIB,*(LPDWORD)lpDIB+::PaletteSize(lpDIB)); //复制头信息和调色版 lpNewDIBBits= ::FindDIBBits(lpNewDIB); lpbmi = (LPBITMAPINFOHEADER)lpNewDIB;
lpbmc = (LPBITMAPCOREHEADER)lpNewDIB;
if (IS_WIN30_DIB(lpDIB))
{
lpbmi->biWidth = NewWidth;
lpbmi->biHeight = NewHeight;
}
else
{
lpbmc->bcWidth = (unsigned short) NewWidth;
lpbmc->bcHeight = (unsigned short) NewHeight;
} //以下进入图像的实际计算;首先计算两个常数
f1=(float) (-0.5*(NewWidth-1)*Cosa-0.5*(NewHeight-1)*Sina+ 0.5*(NewWidth-1) );
f2=(float) ( 0.5*(NewWidth-1)*Sina-0.5*(NewHeight-1)*Cosa+ 0.5*(NewHeight-1) );
//再以此填入图像的实际数据
float iDst,jDst,iSrc,jSrc; for (iDst=0;iDst<NewHeight;iDst++)
for (jDst=0;jDst<NewWidth;jDst++)
{
lpDst=(char*)lpNewDIBBits+ NewLineBytes *(NewHeight-1-(LONG)iDst)+ (LONG)jDst;
jSrc= ((float)jDst)*Cosa+((float)iDst)*Sina+f1 ;
iSrc=-((float)jDst)*Sina+((float)iDst)*Cosa+f2 ;
*lpDst= Interpolation(lpDIBBits,Width,Height,jSrc,iSrc);
} return hDIB;
}