我把一幅图片选入到了内存DC中同时也进行了画了一条线的操作
CDC *pDC = GetDC();
m_dccompatible.CreateCompatibleDC(pDC);
m_dccompatible.m_hDC = m_ImageProcess.LoadImage(pDC->m_hDC, strPath, m_Rect, fSize);
ReleaseDC(pDC); m_dccompatible.MoveTo(20, 20);
m_dccompatible.LineTo(300, 300);在OnPaint中也把内存DC中内容拷贝到了目标DC中显示出来,也确实能在图片上显示出一条线了。
 BitBlt(dc.m_hDC, x, y/*m_Rect.left, m_Rect.top*/, m_Rect.right, m_Rect.bottom,m_dccompatible.m_hDC, m_nXScrollPos, m_nYScrollPos, SRCCOPY);但是现在如何把内存DC m_dccompatible中的图像保存到strPath的图片本身呢?

解决方案 »

  1.   

    我这有一个函数:
    //////////////////////////////////////////////////////////////////
    // Save Bitmap To File
    //////////////////////////////////////////////////////////////////
    BOOL SaveBtimapToFile(HBITMAP hBmp,LPCTSTR pszFileName)         
    {         
    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(L"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(hBmp,   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,hBmp, 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(pszFileName,   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);              return     TRUE;         
    }  
      

  2.   

      //   CDcToBmpView   message   handlers 
    BOOL   SaveBmp(HBITMAP   hBitmap,   CString   FileName) 

    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);   
    //hDC   =   m_pDc-> GetSafeHdc(); 
    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);   return   TRUE; 

    HBITMAP   CopyDCToBitmap(HDC   hScrDC,   LPRECT   lpRect) 

    HDC                 hMemDC;             
    //   屏幕和内存设备描述表 
    HBITMAP         hBitmap,hOldBitmap;       
    //   位图句柄 
    int               nX,   nY,   nX2,   nY2;             
    //   选定区域坐标 
    int               nWidth,   nHeight;             
    //   位图宽度和高度 //   确保选定区域不为空矩形 
    if   (IsRectEmpty(lpRect)) 
    return   NULL; //   获得选定区域坐标 
    nX   =   lpRect-> left; 
    nY   =   lpRect-> top; 
    nX2   =   lpRect-> right; 
    nY2   =   lpRect-> bottom; 
    nWidth   =   nX2   -   nX; 
    nHeight   =   nY2   -   nY; 
    //为屏幕设备描述表创建兼容的内存设备描述表 
    hMemDC   =   CreateCompatibleDC(hScrDC); 
    //   创建一个与屏幕设备描述表兼容的位图 
    hBitmap   =   CreateCompatibleBitmap(hScrDC,   nWidth,   nHeight); 
    //   把新位图选到内存设备描述表中 
    hOldBitmap   =   (HBITMAP)SelectObject(hMemDC,   hBitmap); 
    //   把屏幕设备描述表拷贝到内存设备描述表中 
    StretchBlt(hMemDC,0,0,nWidth,nHeight,hScrDC,nX,nY,nWidth,nHeight,SRCCOPY); 
    //BitBlt(hMemDC,   0,   0,   nWidth,   nHeight,hScrDC,   nX,   nY,   SRCCOPY); 
    //得到屏幕位图的句柄   hBitmap   =   (HBITMAP)SelectObject(hMemDC,   hOldBitmap); 
    //清除   // DeleteDC(hScrDC); 
    DeleteDC(hMemDC); 
    DeleteObject(hOldBitmap); 
    //   返回位图句柄 
    return   hBitmap; 

    void   CDcToBmpView::OnSaveBMP()   

    CDC   *pdc=GetDC(); 
    HBITMAP   hBmp; 
    pdc-> TextOut   (100,100, "asfd "); 
    CRect   rt(100,100,200,200); LPRECT   lprt=&rt; 
      
    pdc-> Ellipse   (rt); hBmp=CopyDCToBitmap(pdc-> GetSafeHdc   (),   lprt); 
    SaveBmp(hBmp,   "f:\\1.bmp "); 
      }