用MFC画了一个散点图,现在需要把图像保存起来,用什么方法好?
最好能详细点解释,我是菜鸟

解决方案 »

  1.   


    CBitmap   bm;  
    bm.CreateCompatibleBitmap(pDC,w,h);  
    CDC   memdc;  
    memdc.CreateCompatibleDC(pDC);  
    CBitmap*pOld=memdc.SelectObject(&bm);  
    memdc.StretchBlt(0,0,w,h,pDC,0,0,w,h,SRCCOPY);  
    BITMAP   btm;  
    bm.GetBitmap(&btm);  
    DWORD   size=btm.bmWidthBytes*btm.bmHeight;  
        LPSTR   lpData=(LPSTR)::GlobalAlloc(GPTR,size);   
    BITMAPINFOHEADER   bih;  
    bih.biBitCount=btm.bmBitsPixel;  
    bih.biClrImportant=0;  
    bih.biClrUsed=0;  
    bih.biCompression=0;  
    bih.biHeight=btm.bmHeight;  
    bih.biPlanes=1;  
    bih.biSize=sizeof(BITMAPINFOHEADER);  
    bih.biSizeImage=size;  
    bih.biWidth=btm.bmWidth;  
    bih.biXPelsPerMeter=0;  
    bih.biYPelsPerMeter=0;  
    GetDIBits(memdc,bm,0,bih.biHeight,lpData,(BITMAPINFO*)&bih,DIB_RGB_COLORS);  

    CString   name;  
    name="c:\\pic.bmp";//保存文件名  
    BITMAPFILEHEADER   bfh;  
    bfh.bfReserved1=bfh.bfReserved2=0;  
    bfh.bfType=((WORD)('M'<<   8)|'B');  
    bfh.bfSize=54+size;  
    bfh.bfOffBits=54;  
    CFile   bf;  
    if(bf.Open(name,CFile::modeCreate|CFile::modeWrite)){  
    bf.WriteHuge(&bfh,sizeof(BITMAPFILEHEADER));  
    bf.WriteHuge(&bih,sizeof(BITMAPINFOHEADER));  
    bf.WriteHuge(lpData,size);  
    bf.Close();  
    }  
    ::GlobalFree(lpData);  
    ReleaseDC(   pDC   );  
        
      

  2.   

    bm.CreateCompatibleBitmap(pDC,w,h);  这个参数怎么定义
      

  3.   

    散点图在哪绘制的?获取相应的DC,然后CreateCompatibleBitmap使用相应的DC.
      

  4.   


    获取客户区大小.
    什么控件?调用其GetClientRect,使用这个Rect的w,h.
      

  5.   

    ntgraph.ocx 用来画图蛮好的
      

  6.   

    什么控件?使用控件的GetClientRect,使用rect的w,h。
      

  7.   


    #include"ENtool.h"
    //图形
    bool ENtool::LHxxDISPLAY_SAVEBMP( char*  FileName,int x,int y,int w,int h )  
    {  
    /*
    HDC hDC = ::GetDC(NULL); //获取屏幕DC
    COLORREF clr = ::GetPixel(hDC, 200, 200); //获取当前鼠标点像素值D3dCom.tp1.x=GetRValue(clr);
    D3dCom.tp1.y=GetGValue(clr); //分解出绿色值
    D3dCom.tp1.z=GetBValue(clr); //分解出蓝色值
    ::ReleaseDC(NULL, hDC); //释放屏幕DC
    */
    HBITMAP  hBitmap;
    RECT rect;
    //获得屏幕分辩率
    rect.left=x;
    rect.top=y;
    rect.right=w+rect.left;
    rect.bottom=h+rect.top;
    // rect.right=GetSystemMetrics(SM_CXSCREEN);
    // rect.bottom=GetSystemMetrics(SM_CYSCREEN);
    //调用截屏函数
    hBitmap=(HBITMAP)GetScreen(&rect);
    //设备描述表  
    HDC  hDC;  
    //当前分辨率下每象素所占字节数  
    int  iBits;  
    //位图中每象素所占字节数  
    WORD  wBitCount;  
    //定义调色板大小,  位图中像素字节大小  ,位图文件大小  ,  写入文件字节数    
    DWORD  dwPaletteSize=0,  dwBmBitsSize=0,  dwDIBSize=0,  dwWritten=0;    
    //位图属性结构    
    BITMAP  Bitmap;      
    //位图文件头结构  
    BITMAPFILEHEADER  bmfHdr;      
    //位图信息头结构    
    BITMAPINFOHEADER  bi;      
    //指向位图信息头结构      
    LPBITMAPINFOHEADER  lpbi;      
    //定义文件,分配内存句柄,调色板句柄    
    HANDLE  fh,  hDib,  hPal,hOldPal=NULL;   
    //计算位图文件每个像素所占字节数    
    hDC  =  CreateDC("DISPLAY",  NULL,  NULL,  NULL);  
    iBits  =  GetDeviceCaps(hDC,  BITSPIXEL)  *  GetDeviceCaps(hDC,  PLANES);    
    DeleteDC(hDC);    
    if  (iBits  <=  1)                        wBitCount  =  1;    
    else  if  (iBits  <=  4)              wBitCount  =  4;    
    else  if  (iBits  <=  8)              wBitCount  =  8;    
    else                                                              wBitCount  =  24;     
    GetObject(hBitmap,  sizeof(Bitmap),  (LPSTR)&Bitmap);  
    bi.biSize                                    =  sizeof(BITMAPINFOHEADER);  
    bi.biWidth                                    =  Bitmap.bmWidth;  
    bi.biHeight                                    =  Bitmap.bmHeight;  
    bi.biPlanes                                    =  1;  
    bi.biBitCount                        =  wBitCount;  
    bi.biCompression            =  BI_RGB;  
    bi.biSizeImage                        =  0;  
    bi.biXPelsPerMeter            =  0;  
    bi.biYPelsPerMeter            =  0;  
    bi.biClrImportant            =  0;  
    bi.biClrUsed                        =  0;   
    dwBmBitsSize  =  ((Bitmap.bmWidth  *  wBitCount  +  31)  /  32)  *  4  *  Bitmap.bmHeight;   
    //为位图内容分配内存    
    hDib  =  GlobalAlloc(GHND,dwBmBitsSize  +  dwPaletteSize  +  sizeof(BITMAPINFOHEADER));    
    lpbi  =  (LPBITMAPINFOHEADER)GlobalLock(hDib);    
    *lpbi  =  bi;    
    //  处理调色板      
    hPal  =  GetStockObject(DEFAULT_PALETTE);    
    if  (hPal)    
    {    
       hDC  =  ::GetDC(NULL);    
       hOldPal  =  ::SelectPalette(hDC,  (HPALETTE)hPal,  FALSE);    
       RealizePalette(hDC);    
    }  
    //  获取该调色板下新的像素值    
    GetDIBits(hDC,  hBitmap,  0,  (UINT)  Bitmap.bmHeight,  (LPSTR)lpbi  +  sizeof(BITMAPINFOHEADER)    
       +dwPaletteSize,            (BITMAPINFO  *)lpbi,  DIB_RGB_COLORS);     
    //恢复调色板      
    if  (hOldPal)    
    {    
       ::SelectPalette(hDC,  (HPALETTE)hOldPal,  TRUE);    
       RealizePalette(hDC);    
       ::ReleaseDC(NULL,  hDC);    

    //创建位图文件      
    fh  =  CreateFile(FileName,  GENERIC_WRITE,0,  NULL,  CREATE_ALWAYS,    
       FILE_ATTRIBUTE_NORMAL    |  FILE_FLAG_SEQUENTIAL_SCAN,  NULL);     
    if  (fh  ==  INVALID_HANDLE_VALUE)    return  FALSE;   
    //  设置位图文件头    
    bmfHdr.bfType  =  0x4D42;  //  "BM"    
    dwDIBSize  =  sizeof(BITMAPFILEHEADER)  +  sizeof(BITMAPINFOHEADER)  +  dwPaletteSize  +  dwBmBitsSize;      
    bmfHdr.bfSize  =  dwDIBSize;    
    bmfHdr.bfReserved1  =  0;    
    bmfHdr.bfReserved2  =  0;    
    bmfHdr.bfOffBits  =  (DWORD)sizeof(BITMAPFILEHEADER)  +  (DWORD)sizeof(BITMAPINFOHEADER)  +  dwPaletteSize;    
    //  写入位图文件头    
    WriteFile(fh,  (LPSTR)&bmfHdr,  sizeof(BITMAPFILEHEADER),  &dwWritten,  NULL);    
    //  写入位图文件其余内容    
    WriteFile(fh,  (LPSTR)lpbi,  dwDIBSize,  &dwWritten,  NULL);    
    //清除      
    GlobalUnlock(hDib);    
    GlobalFree(hDib);    
    CloseHandle(fh);
    DeleteObject(hBitmap);
    return  TRUE;  

    //调用截屏函数 
    HANDLE ENtool::GetScreen(LPRECT lpRect)
    {
    //定义屏幕的DC和内存DC
    HDC hScrDC,hMemDC;
    //定义Bitmap设备
    HANDLE hBitmap,hOldBitmap;
    //定义屏幕坐标变量
    unsigned int nX,nY,nX2,nY2;
    unsigned int nWidth,nHeight;
    //定义屏幕分辩率变量
    unsigned int xScrn,yScrn;
    //确保屏幕矩形不为空
    if(IsRectEmpty(lpRect))
    return NULL;
    //创建屏幕的DC
    hScrDC=CreateDC("DISPLAY",NULL,NULL,NULL);
    //创建的内存DC
    hMemDC=CreateCompatibleDC(hScrDC);
    //将屏幕矩形坐标付给坐标变量
    nX=lpRect->left;
    nY=lpRect->top ;
    nX2=lpRect->right ;
    nY2=lpRect->bottom ;
    //获得屏幕分辩率
    xScrn=GetDeviceCaps(hScrDC,HORZRES);
    yScrn=GetDeviceCaps(hScrDC,VERTRES);
    if(nX<0)
    nX=0;
    if(nY<0)
    nY=0;
    if(nX2>xScrn)
    nX2=xScrn;
    if(nY2>yScrn)
    nY2=yScrn;
    //获得屏幕宽度与长度
    nWidth=nX2-nX;
    nHeight=nY2-nY;
    //获得屏幕图像并付给一个Bitmap设备
    hBitmap=CreateCompatibleBitmap(hScrDC,nWidth,nHeight);
    hOldBitmap=(HBITMAP)SelectObject(hMemDC,hBitmap);
    BitBlt(hMemDC,0,0,nWidth,nHeight,hScrDC,nX,nY,SRCCOPY);
    hBitmap=(HBITMAP)SelectObject(hMemDC,hOldBitmap);
    //清除设备
    DeleteDC(hScrDC);
    DeleteDC(hMemDC);
    return hBitmap;
    }
    void ENtool::LHxxSetPixel(COLORREF color,int w,int h,int x,int y,int count)
    {
    HDC hdc;
    hdc = GetDC(hWnd);
    for(int i=0;i<count;i++)
    {
    int x=rand()%w;
    int y=rand()%h;
    SetPixel(hdc,x,y,color);
    }
    }
    //设窗口为最前
    void  ENtool::LHxxSET_WINISTOP()
    {
    SetWindowPos( hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    }
    //设置窗口位置(居中)(最大化/无窗框)
    void  ENtool::LHxxSET_WINNOMOVE(int Scrw,int Scrh )//case WM_MOVE:用
    {
    SetWindowPos(hWnd, NULL,(GetSystemMetrics(SM_CXFULLSCREEN)-Scrw)/2,
    (GetSystemMetrics(SM_CYFULLSCREEN)-Scrh)/2,
    Scrw, Scrh,0);
    //参数2取-1表示在最顶层显示窗口,取1表示在最底层显示;最后一个参数若取1,表示窗口大小保持不变,取2表示保持位置不变,因此,取3(=1+2)表示大小和位置均保持不变,取0表示将窗口的大小和位置改变为指定值。 
    //+GetSystemMetrics(SM_CYBORDER)
    // D3dCom.tp2.x  = LOWORD(lParam);
    // D3dCom.tp2.y =  HIWORD(lParam);
    /*
    ◎ IDABORT:“Abort”按钮被选择。
      ◎ IDCANCEL:“Cancel”按钮被选择。
      ◎ IDIGNORE:“Ignore”按钮被选择。
      ◎ IDNO:“No”按钮被选择。
      ◎ IDOK:“OK”按钮被选择。
      ◎ IDRETRY:“Retry”按钮被选择。
      ◎ IDYES:“Yes”按钮被选择。
      以上说了这么多,我几乎都忘了我们原来的话题了。总之,当收到WM_CLOSE消息,你可以做两件事儿。一件是你接受默认的处理返回一个值,你若这样做了,应用程序或窗口按照计划关闭;再者,你返回0,应用程序或窗口将保持原样。以下是代码的基本部分:
    MB_OK   The message box contains one pushbutton: OK.
    MB_OKCANCEL   The message box contains two pushbuttons: OK and Cancel.
    MB_RETRYCANCEL   The message box contains two pushbuttons: Retry and Cancel.
    MB_YESNO   The message box contains two pushbuttons: Yes and No.
    MB_YESNOCANCEL
    */
    //if (MessageBox(hMainWindow, "Are you sure want to quit?", "Notice", MB_YESNO | MB_ICONEXCLAMATION) == IDNO)
    //return(0);
    }
    //最大化
    void ENtool::LHxxSHOW_WINMAX()
    {
    ShowWindow( hWnd, SW_SHOWMAXIMIZED );
    UpdateWindow( hWnd );
    }
    //打开EXE程序
    void ENtool::LHxxOPEN_EXE(char *name)
    {
    LPShellExecute pShellExecute = NULL;
    HINSTANCE hInstShell32 = LoadLibrary(TEXT("shell32.dll"));//动态加载连接载
    if (hInstShell32 != NULL)
    {
    //显式链接到 DLL 的进程调用 GetProcAddress 来获取 DLL 导出函数的地址
    pShellExecute = (LPShellExecute)GetProcAddress(hInstShell32, _TWINCE("ShellExecuteA"));
    if( pShellExecute != NULL )
    {
    if(pShellExecute( hWnd, TEXT("open"), name, NULL, NULL, SW_SHOW ) > (HINSTANCE)  32 ){}
    }
    FreeLibrary(hInstShell32);
    hInstShell32=NULL;
    }
    }
    //检测游戏窗口状态;
    void ENtool::setActivateState(int off)
    {
    bActivate=off;
    }
    int ENtool::getActivateState()
    {
    return bActivate;
    }
    //生成随机种子
    void ENtool::RandomIni()
    {
    srand(GetTickCount());
    }
    //创建文件夹
    //0:创建失败; 1:文件夹存在; 2:创建文件夹
    int ENtool::CreateFolder(char *strDir) 

    if(::_chdir(strDir)!=0)  //不存在则创建  

    if(::_mkdir(strDir)==0)  //创建成功 
    {  
    return 2; 
    }  
    else    //创建失败 

    return 0; 


    else //文件夹存在

    return 1; 

      

  8.   

    先获取DC,因为你作图一般都是做在一个HBITMAP对象上的,所以将这个HBITMAP对象保存为BMP文件就行了,下面是保存为BMP文件的代码:
    WORD wbitsCount;//位图中每个像素所占字节数。
           DWORD dwpalettelsize=0;//调色板大小
           DWORD dwbmdibitsize,dwdibsize,dwwritten;
           BITMAP bitmap;//定义了位图的各种的信息。
           BITMAPFILEHEADER bmfhdr;//定义了大小、类型等BMP文件的信息。
           BITMAPINFOHEADER bi;
           LPBITMAPINFOHEADER lpbi;
           HANDLE fh,fdib;
    GetObject(hBitmap,sizeof(BITMAP),(void *)&bitmap);//得到BITMAP结构。
           //以下代码是用BITMAP的信息填充BITMAPINFOHEADER结构
           wbitsCount=bitmap.bmBitsPixel;
    bi.biSize=sizeof(BITMAPINFOHEADER);
           bi.biWidth=bitmap.bmWidth;
           bi.biHeight=bitmap.bmHeight;
           bi.biPlanes=1;
           bi.biBitCount= bitmap.bmBitsPixel ;
           bi.biClrImportant=0;
           bi.biClrUsed=0;
           bi.biCompression=BI_RGB;
           bi.biSizeImage=0;
           bi.biYPelsPerMeter=0;
           bi.biXPelsPerMeter=0;
    //以下代码是获取调色板的长度,调色板现在的用处很少,因为256色的位图已经不多了。
           if(wbitsCount<=8)
                  dwpalettelsize=(1<<wbitsCount)*sizeof(RGBQUAD);
    //计算位图的大小,并分配相应的内存空间,注意的是没有分配BITMAPFILEHEADER。
           dwbmdibitsize=((bitmap.bmWidth*wbitsCount+31)/8)*bitmap.bmHeight;
           fdib=GlobalAlloc(GHND,dwbmdibitsize+dwpalettelsize+sizeof(BITMAPINFOHEADER));
           lpbi=(LPBITMAPINFOHEADER)::GlobalLock(fdib);
           *lpbi=bi;//将bi中的数据写入分配的内存中。
           hdc=::GetDC(NULL);
           GetDIBits(hdc,hBitmap,0,(UINT)bitmap.bmHeight,(LPSTR)lpbi+sizeof(BITMAPINFOHEADER)+dwpalettelsize,(BITMAPINFO *)lpbi,DIB_RGB_COLORS);
    /*GetDIBits是最重要的函数,真正获得位图数据的工作就由它完成,它第一个参数为HDC,第二个参数为位图句柄,第三个参数为扫描行的开始行,一般为0,第四个为结束行,一般就是高度,第四个参数最重要,它表示接收数据的起始地址,这个地址一般是在调色板之后。第五个参数指的是接收BITMAPINFO结构的地址,这个结构上面没有写,它其实就是BITMAPINFO结构加上调色板信息。最后一个参数是格式。一般是DIB_RGB_COLORS*/
    //创建文件以及文件信息头
    fh=CreateFile(FileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL);
           if(fh==INVALID_HANDLE_VALUE)
                  return FALSE;
    bmfhdr.bfType=0x4d42;//BMP类型,一定要这样写
           dwdibsize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+dwbmdibitsize+dwpalettelsize;//文件总长,由几个部分组成
           bmfhdr.bfSize=dwdibsize;
           bmfhdr.bfReserved1=0;
           bmfhdr.bfReserved2=0;
    bmfhdr.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER)+dwpalettelsize;//位图数据相对于文件头的偏移量
    //将文件信息头写入文件
    WriteFile(fh,(LPSTR)&bmfhdr,sizeof(BITMAPFILEHEADER),&dwwritten,NULL);
    //将数据写入文件,包含BITMAPINFO结构、调色板、数据
    WriteFile(fh,(LPSTR)lpbi,dwdibsize,&dwwritten,NULL);
    //关闭相关句柄
    ::GlobalUnlock(fdib);
           ::GlobalFree(fdib);
           ::CloseHandle(fh);
    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wltg2001/archive/2008/04/17/2300258.aspx