比如,CBitmap是DDB还是DIB.

解决方案 »

  1.   

    DIB是设备无依赖位图,DDB是设备依赖位图,CBitmap可以是DIB
      

  2.   

    ddb设备相关
    dib设备无关
    图象要显示出来必须转换成设备相关位图
      

  3.   

    to orbit:
    CBitmap什么时候是DIB,什么时候是DDB.
      

  4.   

    把DDB转换成DIB
    设备相关位图(DDB)显示方式是尽可能与显示设备驱动程序相匹配,这样,DDB不可能与其他显示设备兼容;而设备无关位图(DIB)能与所有显示设备兼容,但是,其缺点在于显示速度比较慢。我们需要把DDB转换为DIB的一种情况是,需要将位图保存到一个文件中。下面是其实现的代码。// DDBToDIB - Creates a DIB from a DDB
    // bitmap - Device dependent bitmap
    // dwCompression - Type of compression - see BITMAPINFOHEADER
    // pPal - Logical palette
    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;
    }
      

  5.   

    把DIB转换成DDB
    你可以把一个设备无关位图(DIB)在不转换成设备相关位图(DDB)的情况下显示到设备环境中,但是,这样做显示速度将慢很多。如果进行转换,将提高显示速度。下面是其实现代码。
    HBITMAP DIBToDDB( HANDLE hDIB )
    {
    LPBITMAPINFOHEADER lpbi;
    HBITMAP  hbm;
    CPalette pal;
    CPalette* pOldPal;
    CClientDC dc(NULL); if (hDIB == NULL)
    return NULL; lpbi = (LPBITMAPINFOHEADER)hDIB; int nColors = lpbi->biClrUsed ? lpbi->biClrUsed : 
    1 << lpbi->biBitCount; BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
    LPVOID lpDIBBits;
    if( bmInfo.bmiHeader.biBitCount > 8 )
    lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors + 
    bmInfo.bmiHeader.biClrUsed) + 
    ((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
    else
    lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors); // Create and select a logical palette if needed
    if( nColors <= 256 && dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE) { UINT nSize="sizeof(LOGPALETTE)" + (sizeof(PALETTEENTRY) * nColors); LOGPALETTE *pLP="(LOGPALETTE" *) new BYTE[nSize]; pLP->palVersion = 0x300;
    pLP->palNumEntries = nColors; for( int i=0; i palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed;
    pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen;
    pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue;
    pLP->palPalEntry[i].peFlags = 0;
    } pal.CreatePalette( pLP ); delete[] pLP; // Select and realize the palette
    pOldPal = dc.SelectPalette( &pal, FALSE );
    dc.RealizePalette();
    }
    hbm = CreateDIBitmap(dc.GetSafeHdc(), // handle to device context
    (LPBITMAPINFOHEADER)lpbi, // pointer to bitmap info header 
    (LONG)CBM_INIT, // initialization flag
    lpDIBBits, // pointer to initialization data 
    (LPBITMAPINFO)lpbi, // pointer to bitmap info
    DIB_RGB_COLORS ); // color-data usage  if (pal.GetSafeHandle())
    dc.SelectPalette(pOldPal,FALSE); return hbm;
    }
      

  6.   

    把位图写入一个BMP文件
    如果具有一个设备无关的位图句柄,把一个位图写入BMP文件非常简单:在位图内容之后写入BITMAPINFOHEADER信息即可。需要设置BITMAPINFOHEADER的三个成员是bfType,其值为"BM",bfSize,其值是位图的大小,以及,bfOffBits,其值为文件开始到位图位的偏移量。 // WriteDIB - Writes a DIB to file
    // Returns - TRUE on success
    // szFile - Name of file to write to
    // hDIB - Handle of the DIB
    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;
    }
      

  7.   

    最后请求帮助支持一下:http://community.csdn.net/Expert/topic/3768/3768074.xml?temp=.9844171
      

  8.   

    DIB和DDB,在MSDN中对它们的解释是: device-independent bitmap (DIB) 
    An array of bits combined with several structures that specify the width and height of the bitmap image (in pixels), the color format of the device where the image was created, and the resolution of the device used to create that image. A DIB generally has its own color table, and can therefore be displayed on a variety of devices. device-dependent bitmap (DDB) 
    An array of bits that can only be used with a particular display or printer. DIB由于自带颜色表,理论上说在不同的设备上显示时均可按原来的颜色还原显示,或仿真显示,但是很明显颜色表需要消耗一定的存储空间,并且在每次显示时均要对颜色进行处理,因此速度较慢。DDB由于直接对颜色位平面进行记录,因此显示速度最快,但是在不同的设备上显示时不能保证颜色的还原。主要区别就是颜色标,一般来说,在剪贴板中存放的是DDB(比如截屏的时候获得的),在文件中存放的是DIB