问题描述
- mfc 图片控件旋转问题,一次旋转90°
-
mfc 图片控件旋转,这个可以旋转么?怎么写代码?求大神指导,菜鸟一个
解决方案
控件没有办法旋转,但是上面绘制的图形或者文字是可以得。
解决方案二:
第一步,你必须知道位图即BMP格式的文件的结构.
??????????????位图(bmp)文件由以下几个部分组成:
?????????????????????1.BITMAPFILEHEADER,它的定义如下:
?????????????????????????typedef?struct?tagBITMAPFILEHEADER?{?
????????????????????????????WORD????bfType;?????????//必须为BM
????????????????????????????DWORD???bfSize;?????????//文件大小
????????????????????????????WORD????bfReserved1;?//必须为0
????????????????????????????WORD????bfReserved2;?//必须为0
????????????????????????????DWORD???bfOffBits;????//从ITMAPFILEHEADER到存放bmp数据的偏移量???????????????????????????????????
?????????????????????????}?BITMAPFILEHEADER,?*PBITMAPFILEHEADER;?
???????????????????2.BITMAPINFOHEADER,它的定义如下:
???????????????????????typedef?struct?tagBITMAPINFOHEADER{
???????????????????????????????????DWORD??biSize;??//此结构的大小,可用sizeof(BITMAPINFOHEAER)得到
???????????????????????????????????LONG???biWidth;?//位图宽度,以象素为单位
???????????????????????????????????LONG???biHeight;?//位图高度,以象素为单位
???????????????????????????????????WORD???biPlanes;?//必须为1
???????????????????????????????????WORD???biBitCount;//位图象素位数,可为0,1,4,8,24,32?
???????????????????????????????????DWORD??biCompression;?
???????????????????????????????????DWORD??biSizeImage;?//(仅用于压缩)
???????????????????????????????????LONG???biXPelsPerMeter;?//一米横向象素数
???????????????????????????????????LONG???biYPelsPerMeter;?//一米纵向象素数
???????????????????????????????????DWORD??biClrUsed;//?(非零用语短颜色表)
???????????????????????????????????DWORD??biClrImportant;?
??????????????????????}?BITMAPINFOHEADER,?*PBITMAPINFOHEADER;?
???????由于以上信息可以直接从MSDN上查到,所以只做简单介绍,你可以自己查看NSDN帮助,上面有很详细的介绍.
??????????????3.DIB位图像.这里放的是真正的位图数据.
????????知道了位图的存放格式,下面我们就可以很容易的把它读如内存.
???????第二步,读入bmp图像
???????LPCTSTR?lpszFileName4=untitled.bmp;???//文件路径
??????CFile?file;?????????????????????????????????????//用于读取BMP文件
??????BITMAPFILEHEADER?bfhHeader;//bmp文件头
?????BITMAPINFOHEADER?bmiHeader;?//bmp格式头?
??????LPBITMAPINFO?lpBitmapInfo;????//bmp格式具体信息
??????int?bmpWidth=0;?????????????????????????//图片宽度
??????int?bmpHeight?=?0;??????????????????????//图片高度????????????
??????if(!file.Open(lpszFileName,CFile::modeRead))
??????????????return?;??????????????????????????????//打开文件
??????file.Read(&bfhHeader,sizeof(BITMAPFILEHEADER));//读取文件头
??????if(bfhHeader.bfType!=((WORD)?(M<<8)|B))???????????//判断是否是BM
??????????????return?;
??????if(bfhHeader.bfSize!=file.GetLength())
??????????????return?;
???????????????????????????????
?????if?(file.Read((LPSTR)&bmiHeader,?sizeof(bmiHeader))?!=?sizeof(bmiHeader))
??????????????return?;
?????bmpHeight?=?bmiHeader.biHeight;//得到高度和宽度
?????bmpWidth?=?bmiHeader.biWidth;
?????file.SeekToBegin();
?????file.Read(&bfhHeader,sizeof(BITMAPFILEHEADER));?
?????UINT?uBmpInfoLen=(UINT)?bfhHeader.bfOffBits-sizeof(BITMAPFILEHEADER);
?????lpBitmapInfo=(LPBITMAPINFO)?new?BYTE[uBmpInfoLen];
?????file.Read((LPVOID)?lpBitmapInfo,uBmpInfoLen);
?????if((*?(LPDWORD)(lpBitmapInfo))!=sizeof(BITMAPINFOHEADER))
??????????????return?;
?????DWORD?dwBitlen=bfhHeader.bfSize?-?bfhHeader.bfOffBits;
?????LPVOID?lpSrcBits=new?BYTE[dwBitlen];??????????//将数据读入lpSrcBits数组
?????file.ReadHuge(lpSrcBits,dwBitlen);
?????file.Close();?????????????????????????????????????????????????????//关闭文件
?????下面我们将图片显示在屏幕上:
?????第三步,显示图片
?????CClientDC??hDC(this);?
?????StretchDIBits(hDC,0,0,bmpWidth,bmpHeight,0,0,bmpWidth,bmpHeight,
??????????????????????????lpSrcBits,lpBitmapInfo,DIB_RGB_COLORS,SRCCOPY);
?????第四步,将图片读入内存设备环境
??????HDC?dcSrc;
??????HBITMAP?bitmap;
??????dcSrc=CreateCompatibleDC(hDC);//得到一个内存设备环境
??????bitmap?=?CreateCompatibleBitmap(hDC,bmpWidth,bmpHeight);
??????SelectObject(dcSrc,bitmap);
??????BitBlt(dcSrc,0,0,bmpWidth,bmpHeight,hDC,0,0,SRCCOPY);//这一步很重要
??????第五步,实现位图旋转
??????我们假设旋转位图的函数原形如下:
??????void?RotateBitmap(HDC?dcSrc,int?SrcWidth,int?SrcHeight,double?angle,HDC?pDC);
?????/*参数解释如下://///////////////////////////////////////////////////////////////////////////
????????HDC?dcSrc:要旋转的位图的内存设备环境,就是第四步创建的
????????int?SrcWidth:要旋转位图的宽度
????????int?SrcHeight:要旋转位图的高度
???????double?angle:所要旋转的角度,以弧度为单位???
???????HDC?pDC:第三步得到的当前屏幕设备环境
*///////////////////////////////////////////////////////////////////////////////////////////////////////
//以下是函数实现细节
void?RotateAnyAngle(HDC?dcSrc,int?SrcWidth,int?SrcHeight,double?angle)
{
?double?x1,x2,x3;
?double?y1,y2,y3;
?double?maxWidth,maxHeight,minWidth,minHeight;
?double?srcX,srcY;
?double?sinA,cosA;
?double?DstWidth;
?double?DstHeight;
?HDC?dcDst;//旋转后的内存设备环境
?HBITMAP?newBitmap;
?sinA?=?sin(angle);
?cosA?=?cos(angle);
?x1?=?-SrcHeight?*?sinA;
????y1?=?SrcHeight?*?cosA;
????x2?=?SrcWidth?*?cosA?-?SrcHeight?*?sinA;
????y2?=?SrcHeight?*?cosA?+?SrcWidth?*?sinA;
????x3?=?SrcWidth?*?cosA;
????y3?=?SrcWidth?*?sinA;
?minWidth?=?x3>(x1>x2?x2:x1)?(x1>x2?x2:x1):x3;
?minWidth?=?minWidth>0?0:minWidth;
?minHeight?=?y3>(y1>y2?y2:y1)?(y1>y2?y2:y1):y3;
?minHeight?=?minHeight>0?0:minHeight;
?maxWidth?=?x3>(x1>x2?x1:x2)?x3:(x1>x2?x1:x2);
?maxWidth?=?maxWidth>0?maxWidth:0;
?maxHeight?=?y3>(y1>y2?y1:y2)?y3:(y1>y2?y1:y2);
?maxHeight?=?maxHeight>0?maxHeight:0;
?DstWidth?=?maxWidth?-?minWidth;
????DstHeight?=?maxHeight?-?minHeight;
?dcDst?=?CreateCompatibleDC(dcSrc);
?newBitmap?=?CreateCompatibleBitmap(dcSrc,(int)DstWidth,(int)DstHeight);
?SelectObject(dcDst,newBitmap);
?for(?int?I?=?0?;I
?{
????for(int?J?=?0?;J
????{
???????srcX?=?(J?+?minWidth)?*?cosA?+?(I?+?minHeight)?*?sinA;
???????srcY?=?(I?+?minHeight)?*?cosA?-?(J?+?minWidth)?*?sinA;
???????if(?(srcX?>=?0)?&&?(srcX?<=?SrcWidth)?&&(srcY?>=?0)?&&?(srcY?<=?SrcHeight))
??????{
??????????????BitBlt(dcDst,?J,?I,?1,?1,?dcSrc,(int)srcX,?(int)srcY,?SRCCOPY);
??????}
???}
?}
???//显示旋转后的位图
???BitBlt(hDC,200,200,(int)DstWidth,(int)DstHeight,dcDst,0,0,SRCCOPY);
???DeleteObject(newBitmap);
???DeleteDC(dcDst);
}
??????最后我们调用就可以了:
??????double?angle?=?(45/180.0)*3.14159;//旋转45Degree,可为任意角度
??????RotateAnyAngle(dcSrc,bmpWidth,bmpHeight,angle,);
?????到这里就大功告成了.
解决方案三:
图片旋转的MFC程序