家庭医药是国家级杂志:MFC中BMP图片旋转任意角度、用于绘制模拟时钟表针

来源:百度文库 编辑:偶看新闻 时间:2024/05/05 05:51:20

filepath为图片路径,angle为旋转角度。旋转以pCenter为中心进行旋转,并且pCenter将位于图片中心

用于绘制模拟时钟表针

void CXXXXX::DrawBmp(CDC *pDC, CString filepath, double angle)

{

 

double SrcWidth = 0;//图片宽度

double SrcHeight = 0;//图片高度

 

CFile   file;                //用于读取BMP文件 

BITMAPFILEHEADER   bfhHeader;//bmp文件头 

BITMAPINFOHEADER   bmiHeader;   //bmp格式头   

 

LPBITMAPINFO   lpBitmapInfo;         //bmp格式具体信息 

 

if(!file.Open(filepath,CFile::modeRead)) 

return;                                                             //打开文件 

file.Read(&bfhHeader,sizeof(BITMAPFILEHEADER));//读取文件头 

if(bfhHeader.bfType!=0x4d42)                     //判断是否是BM 

return; 

if(bfhHeader.bfSize!=file.GetLength()) 

return; 

 

if(file.Read((LPSTR)&bmiHeader,sizeof(bmiHeader)) != sizeof(bmiHeader)) 

return;

 

SrcHeight   =   bmiHeader.biHeight; //得到高度和宽度 

SrcWidth    =   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.Read(lpSrcBits,dwBitlen); 

file.Close(); //关闭文件 

 

 

CDC bmpDC;

bmpDC.CreateCompatibleDC(pDC);

CBitmap bmp;

bmp.CreateCompatibleBitmap(pDC,SrcWidth,SrcHeight);

bmpDC.SelectObject(&bmp);

 

StretchDIBits(bmpDC.m_hDC,0,0,SrcWidth,SrcHeight,0,0,bmiHeader.biWidth,bmiHeader.biHeight,lpSrcBits,lpBitmapInfo,DIB_RGB_COLORS,MERGECOPY); 

//StretchDIBits不能去掉。将图片贴到bmpDC中

 

 

double x1,x2,x3; 

double y1,y2,y3; 

double maxWidth,maxHeight,minWidth,minHeight; 

double srcX,srcY; 

double sinA,cosA; 

double DstWidth; 

double DstHeight; 

 

angle=angle/ 180.0 * 3.14159265;

sinA = sin(angle); 

cosA = cos(angle); 

 

x1 = SrcWidth * cosA;

y1 = SrcWidth * sinA;

x2 = SrcWidth * cosA - SrcHeight * sinA;

y2 = SrcWidth * sinA + SrcHeight * cosA;

x3 = -SrcHeight *sinA;

y3 = SrcHeight  *cosA;

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 = abs(maxWidth - minWidth)+1; 

DstHeight =abs(maxHeight - minHeight)+1; 

 

 

HDC dcDst;//旋转后的内存设备环境 

HBITMAP newBitmap; 

dcDst = CreateCompatibleDC(pDC->m_hDC); 

newBitmap = CreateCompatibleBitmap(pDC->m_hDC,(int)DstWidth,(int)DstHeight); 

SelectObject(dcDst,newBitmap);

::FillRect(dcDst,CRect(0,0,DstWidth,DstHeight),CBrush(RGB(255,255,255)));

int i = 0;

int j = 0;

for(i = 0; i < DstHeight; i++) 

for(j = 0; j  <  DstWidth; 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, bmpDC.m_hDC, (int)srcX, (int)srcY, SRCCOPY); 

 

CRect rtHour;

rtHour.left=pCenter.x-DstWidth/2;

rtHour.right=rtHour.left+DstWidth;

rtHour.top=pCenter.y-DstHeight/2;

rtHour.bottom=rtHour.top+DstHeight;

TransparentBlt(pDC->m_hDC,rtHour.left,rtHour.top,rtHour.Width(),rtHour.Height(),dcDst,0,0,rtHour.Width(),rtHour.Height(),RGB(255,255,255));

 

 

delete[] lpBitmapInfo;

delete[] lpSrcBits;

lpBitmapInfo = NULL;

lpSrcBits = NULL;

 

::ZeroMemory(&bfhHeader,sizeof(bfhHeader));

::ZeroMemory(&bmiHeader,sizeof(bmiHeader));

::ZeroMemory(&lpBitmapInfo,sizeof(lpBitmapInfo));

 

 

bmpDC.DeleteDC();

bmp.DeleteObject();

 

DeleteDC(dcDst); 

DeleteObject(newBitmap); 

}