(2002-06-02 13:36:56)   飞鸽
CBitmap Bitmap;
Bitmap.LoadBimap(IDSource)CClientDC dcScrreen(this);
CDC MemDC;
MemDC.CreateCompatibleDC(&dcScreen);
MemDC.SelectObjecg(&Bitmap);
MemDc.Arc();//画图;
BITMAP bm;
Bitmap.GetBitmap(&bm);
Width = bm.bmWidth;
Height = bm.bmHeight;
dcScreen.BtiBlt(0,0,Width,Height,dcScreen,0,0,SRCCOPY);

解决方案 »

  1.   

    你说得应该是指将圆弧以位图形式保存到文件,是吧。
    我上次说过一种方法。
    先照楼上的这位兄弟的做法,得到BITMAP结构。
    即Bitmap.GetBitmap((&bm);
    看一下BITMAP结构的定义:
    typedef struct tagBITMAP {  /* bm */
        int     bmType;
        int     bmWidth;
        int     bmHeight;
        int     bmWidthBytes;
        BYTE    bmPlanes;
        BYTE    bmBitsPixel;
        LPVOID  bmBits;
    } BITMAP;
    由此结构即可得到图形数据指针和相关信息,下面再给出位图文件的结构:
    ---- 一、BMP文件结构 ---- 1. BMP文件组成 ---- BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。 ---- 2. BMP文件头 ---- BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息。 ---- 其结构定义如下: typedef struct tagBITMAPFILEHEADER
    {
    WORDbfType;   // 位图文件的类型,必须为BM
    DWORD   bfSize;   // 位图文件的大小,以字节为单位
    WORDbfReserved1;  // 位图文件保留字,必须为0
    WORDbfReserved2;  // 位图文件保留字,必须为0
    DWORD   bfOffBits; // 位图数据的起始位置,以相对于位图
    // 文件头的偏移量表示,以字节为单位
    } BITMAPFILEHEADER;---- 3. 位图信息头 BMP位图信息头数据用于说明位图的尺寸等信息。
    typedef struct tagBITMAPINFOHEADER{
       DWORD  biSize;   // 本结构所占用字节数
       LONGbiWidth;  // 位图的宽度,以像素为单位
       LONGbiHeight; // 位图的高度,以像素为单位
       WORD   biPlanes; // 目标设备的级别,必须为1
       WORD   biBitCount// 每个像素所需的位数,必须是1(双色),
      // 4(16色),8(256色)或24(真彩色)之一
       DWORD  biCompression;   // 位图压缩类型,必须是 0(不压缩),
      // 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
       DWORD  biSizeImage; // 位图的大小,以字节为单位
       LONGbiXPelsPerMeter; // 位图水平分辨率,每米像素数
       LONGbiYPelsPerMeter;  // 位图垂直分辨率,每米像素数
       DWORD  biClrUsed;// 位图实际使用的颜色表中的颜色数
       DWORD  biClrImportant;// 位图显示过程中重要的颜色数
    } BITMAPINFOHEADER;---- 4. 颜色表 ---- 颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义 一种颜色。RGBQUAD结构的定义如下: typedef struct tagRGBQUAD {
    BYTErgbBlue;// 蓝色的亮度(值范围为0-255)
    BYTErgbGreen;   // 绿色的亮度(值范围为0-255)
    BYTErgbRed; // 红色的亮度(值范围为0-255)
    BYTErgbReserved;// 保留,必须为0
    } RGBQUAD;
    颜色表中RGBQUAD结构数据的个数有biBitCount来确定:
    当biBitCount=1,4,8时,分别有2,16,256个表项;
    当biBitCount=24时,没有颜色表项。
       位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:
    typedef struct tagBITMAPINFO {
       BITMAPINFOHEADER bmiHeader;   // 位图信息头
       RGBQUAD  bmiColors[1];  // 颜色表
    } BITMAPINFO;---- 5. 位图数据 ---- 位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到 上。位图的一个像素值所占的字节数: 当biBitCount=1时,8个像素占1个字节;
    当biBitCount=4时,2个像素占1个字节;
    当biBitCount=8时,1个像素占1个字节;
    当biBitCount=24时,1个像素占3个字节;Windows规定一个扫描行所占的字节数必须是 4的倍数(即以long为单位),不足的以0填充, 一个扫描行所占的字节数计算方法: DataSizePerLine= (biWidth* biBitCount+31)/8; // 一个扫描行所占的字节数 DataSizePerLine= DataSizePerLine/4*4; // 字节数必须是4的倍数 位图数据的大小(不压缩情况下): DataSize= DataSizePerLine* biHeight; 代码自己搞定吧。
      

  2.   

    假设你有CDC *pDC,bitmap的长cx高cy,文件名是lpszFile,你要的代码就是ArcToBitmap(),调用的函数包括DDBToDIB()和WriteDIB():HANDLE DDBToDIB(CBitmap& bitmap, DWORD dwCompression, CPalette* pPal);
    BOOL WriteDIB( LPTSTR szFile, HANDLE hDIB);
    BOOL ArcToBitmap(CDC *pDC, int cx, int cy, LPCSTR lpszFile);
    HANDLE DDBToDIB(CBitmap& bitmap, DWORD dwCompression, CPalette* pPal)
    {
    BITMAP bm;
    BITMAPINFOHEADER bi;
    LPBITMAPINFOHEADER  lpbi;
    DWORD dwLen;
    HANDLE hDIB;
    HANDLE handle;
    HDC  hDC;
    HPALETTE hPal;
    ASSERT( bitmap.GetSafeHandle() ); // The function has no arg for bitfields
    if( dwCompression == BI_BITFIELDS )
    return NULL; // If a palette has not been supplied use defaul palette
    hPal = (HPALETTE) pPal->GetSafeHandle();
    if (hPal==NULL)
    hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE); // Get bitmap information
    bitmap.GetObject(sizeof(bm),(LPSTR)&bm); // Initialize the bitmapinfoheader
    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = bm.bmWidth;
    bi.biHeight  = bm.bmHeight;
    bi.biPlanes  = 1;
    bi.biBitCount = bm.bmPlanes * bm.bmBitsPixel;
    bi.biCompression = dwCompression;
    bi.biSizeImage = 0;
    bi.biXPelsPerMeter = 0;
    bi.biYPelsPerMeter = 0;
    bi.biClrUsed = 0;
    bi.biClrImportant = 0; // Compute the size of the  infoheader and the color table
    int nColors = (1 << bi.biBitCount);
    if( nColors > 256 ) 
    nColors = 0;
    dwLen  = bi.biSize + nColors * sizeof(RGBQUAD); // We need a device context to get the DIB from
    hDC = ::GetDC(NULL);
    hPal = SelectPalette(hDC,hPal,FALSE);
    RealizePalette(hDC); // Allocate enough memory to hold bitmapinfoheader and color table
    hDIB = GlobalAlloc(GMEM_FIXED,dwLen); if (!hDIB){
    SelectPalette(hDC,hPal,FALSE);
    ::ReleaseDC(NULL,hDC);
    return NULL;
    } lpbi = (LPBITMAPINFOHEADER)hDIB; *lpbi = bi; // Call GetDIBits with a NULL lpBits param, so the device driver 
    // will calculate the biSizeImage field 
    GetDIBits(hDC, (HBITMAP)bitmap.GetSafeHandle(), 0L, (DWORD)bi.biHeight,
    (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS); bi = *lpbi; // If the driver did not fill in the biSizeImage field, then compute it
    // Each scan line of the image is aligned on a DWORD (32bit) boundary
    if (bi.biSizeImage == 0){
    bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8) 
    * bi.biHeight; // If a compression scheme is used the result may infact be larger
    // Increase the size to account for this.
    if (dwCompression != BI_RGB)
    bi.biSizeImage = (bi.biSizeImage * 3) / 2;
    } // Realloc the buffer so that it can hold all the bits
    dwLen += bi.biSizeImage;
    if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))
    hDIB = handle;
    else{
    GlobalFree(hDIB); // Reselect the original palette
    SelectPalette(hDC,hPal,FALSE);
    ::ReleaseDC(NULL,hDC);
    return NULL;
    } // Get the bitmap bits
    lpbi = (LPBITMAPINFOHEADER)hDIB; // FINALLY get the DIB
    BOOL bGotBits = GetDIBits( hDC, (HBITMAP)bitmap.GetSafeHandle(),
    0L, // Start scan line
    (DWORD)bi.biHeight, // # of scan lines
    (LPBYTE)lpbi  // address for bitmap bits
    + (bi.biSize + nColors * sizeof(RGBQUAD)),
    (LPBITMAPINFO)lpbi, // address of bitmapinfo
    (DWORD)DIB_RGB_COLORS); // Use RGB for color table if( !bGotBits )
    {
    GlobalFree(hDIB);

    SelectPalette(hDC,hPal,FALSE);
    ::ReleaseDC(NULL,hDC);
    return NULL;
    } SelectPalette(hDC,hPal,FALSE);
    ::ReleaseDC(NULL,hDC);
    return hDIB;}BOOL WriteDIB( LPTSTR szFile, HANDLE hDIB)
    {
    BITMAPFILEHEADER hdr;
    LPBITMAPINFOHEADER lpbi; if (!hDIB)
    return FALSE; CFile file;
    if( !file.Open( szFile, CFile::modeWrite|CFile::modeCreate) )
    return FALSE; lpbi = (LPBITMAPINFOHEADER)hDIB; int nColors = 1 << lpbi->biBitCount; // Fill in the fields of the file header 
    hdr.bfType = ((WORD) ('M' << 8) | 'B'); // is always "BM"
    hdr.bfSize = GlobalSize (hDIB) + sizeof( hdr );
    hdr.bfReserved1  = 0;
    hdr.bfReserved2  = 0;
    hdr.bfOffBits = (DWORD) (sizeof( hdr ) + lpbi->biSize +
    nColors * sizeof(RGBQUAD)); // Write the file header 
    file.Write( &hdr, sizeof(hdr) ); // Write the DIB header and the bits 
    file.Write( lpbi, GlobalSize(hDIB) ); return TRUE;}BOOL ArcToBitmap(CDC *pDC, int cx, int cy, LPCSTR lpszFile)
    {
    CDC  memDC;
    memDC.CreateCompatibleDC(pDC);  CBitmap  bitmap;
    bitmap.CreateCompatibleBitmap(pDC, cx, cy);
    CBitmap* pOldBitmap = memDC.SelectObject(&bitmap); // do your operation here:
    memDC.Arc(......); // Create logical palette if device support a palette
    CPalette pal;
    if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE )
    {
    UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);
    LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
    pLP->palVersion = 0x300; pLP->palNumEntries = 
    GetSystemPaletteEntries( dc, 0, 255, pLP->palPalEntry ); // Create the palette
    pal.CreatePalette( pLP ); delete[] pLP;
    } memDC.SelectObject(pOldBitmap); // Convert the bitmap to a DIB
    HANDLE hDIB = DDBToDIB(bitmap, BI_RGB, &pal ); if( hDIB == NULL )
    return FALSE; // Write it to file
    WriteDIB(lpszFile, hDIB); // Free the memory allocated by DDBToDIB for the DIB
    GlobalFree(hDIB);
    return TRUE;
    }
      

  3.   

    假设你有CDC *pDC,bitmap的长cx高cy,
    文件名是lpszFile,
    你要的代码就是ArcToBitmap(),
    调用的函数包括DDBToDIB()和WriteDIB():
    //首先就是定义CDC *pDC的初始化问题,我建的是一个*.bmp文件,该怎么初始化pDC?//然后是这个BOOL ArcToBitmap(CDC *pDC, int cx, int cy, LPCSTR lpszFile)函数中:
    if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE )          
             //说我dc没有定义,我该怎么定义? {                                                             UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);
    LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
    pLP->palVersion = 0x300;
      

  4.   

    1. 关于CDC *pDC的问题
    在Windows中,要作图,必须要有DC(显示设备的context),而DC一般是窗口DC或打印DC。你可以选择一个窗口,获取该窗口的DC,在你的程序中使用。你可以选择你应用程序的主窗口,或者直接使用屏幕的DC:
    方法一:
    CWnd *pWnd = AfxGetMainWnd();
    CClientDC dc(pWnd);
    则:CDC *pDC = &dc;
    方法二:
    HDC hDC = GetDC(NULL);
    则:CDC *pDC = CDC::FromHandle(hDC);2. if(dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
    这一句是我疏忽写错了,应该是if(pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
      

  5.   

    1. 关于CDC *pDC的问题
    在Windows中,要作图,必须要有DC(显示设备的context),而DC一般是窗口DC或打印DC。你可以选择一个窗口,获取该窗口的DC,在你的程序中使用。你可以选择你应用程序的主窗口,或者直接使用屏幕的DC:
    方法一:
    CWnd *pWnd = AfxGetMainWnd();
    CClientDC dc(pWnd);
    则:CDC *pDC = &dc;
    方法二:
    HDC hDC = GetDC(NULL);
    则:CDC *pDC = CDC::FromHandle(hDC);2. if(dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
    这一句是我疏忽写错了,应该是if(pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
      

  6.   

    1. 关于CDC *pDC的问题
    在Windows中,要作图,必须要有DC(显示设备的context),而DC一般是窗口DC或打印DC。你可以选择一个窗口,获取该窗口的DC,在你的程序中使用。你可以选择你应用程序的主窗口,或者直接使用屏幕的DC:
    方法一:
    CWnd *pWnd = AfxGetMainWnd();
    CClientDC dc(pWnd);
    则:CDC *pDC = &dc;
    方法二:
    HDC hDC = GetDC(NULL);
    则:CDC *pDC = CDC::FromHandle(hDC);2. if(dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
    这一句是我疏忽写错了,应该是if(pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)