• MFC中BMP图片旋转任意角度、用于绘制模拟时钟表针


    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); 

    }

  • 相关阅读:
    Windows自带Android模拟器启动失败
    Xamarin.Android提示找不到mono.Android.Support.v4
    Xamarin提示Build-tools版本过老
    Xamarin Android布局文件没有智能提示
    Xamarin.iOS模拟器调试找不到资源文件
    彻底卸载 RAD Studio 2009/2010/XE+ 的步骤
    Delphi版本号对照
    RAD Studio 2010 环境设置(转)
    C语言写的俄罗斯方块
    字符编解码的故事–ASCII,ANSI,Unicode,Utf-8区别
  • 原文地址:https://www.cnblogs.com/ezhong/p/2171493.html
Copyright © 2020-2023  润新知