如何让任何bmp文件转化为24位的bmp??希望可以给出具体代码!

解决方案 »

  1.   

    你的意思是把32位,16位,8位,4位,2位bmp图像转为24位吗?
       我认为无非就是将位图数据变为3个字节表示一个像素,然后修改信息头和文件头。(不用调色板)
    8位的最简单了,把原位图数据的每个字节扩成3个即可。
    4位,2位类似,先逐个取出原位图数据,再扩成3个字节即可。
    16位彩色图像的数据好像是5位,6位,5位,把它们分别扩成8位即可。
    至于32位的,我就不大清楚了。
       以上只是本人的一些想法,仅供参考。我也没有具体实现过。
      

  2.   

    ////////////////////////////////////////////////////////////////////////////////
    bool CxImage::DecreaseBpp(DWORD nbit, bool errordiffusion, RGBQUAD* ppal)
    {
    if (!pDib) return false;
    if (head.biBitCount <  nbit) return false;
    if (head.biBitCount == nbit) return true; long er,eg,eb;
    RGBQUAD c,ce; CxImage tmp;
    tmp.CopyInfo(*this);
    tmp.Create(head.biWidth,head.biHeight,(WORD)nbit,info.dwType);#if CXIMAGE_SUPPORT_SELECTION
    tmp.SelectionCopy(*this);
    #endif //CXIMAGE_SUPPORT_SELECTION#if CXIMAGE_SUPPORT_ALPHA
    tmp.AlphaCopy(*this);
    #endif //CXIMAGE_SUPPORT_ALPHA switch (tmp.head.biBitCount){
    case 1:
    if (ppal) tmp.SetPalette(ppal,16);
    else {
    tmp.SetPaletteColor(0,0,0,0);
    tmp.SetPaletteColor(1,255,255,255);
    }
    break;
    case 4:
    if (ppal) tmp.SetPalette(ppal,16);
    else tmp.SetStdPalette();
    break;
    case 8:
    if (ppal) tmp.SetPalette(ppal);
    else tmp.SetStdPalette();
    break;
    default:
    return false;
    } for (long y=0;y<head.biHeight;y++){
    if (info.nEscape) break;
    info.nProgress = (long)(100*y/head.biHeight);
    for (long x=0;x<head.biWidth;x++){
    if (!errordiffusion){
    tmp.SetPixelColor(x,y,GetPixelColor(x,y));
    } else {
    c=GetPixelColor(x,y);
    tmp.SetPixelColor(x,y,c); ce=tmp.GetPixelColor(x,y);
    er=(long)c.rgbRed - (long)ce.rgbRed;
    eg=(long)c.rgbGreen - (long)ce.rgbGreen;
    eb=(long)c.rgbBlue - (long)ce.rgbBlue; c = GetPixelColor(x+1,y);
    c.rgbRed = (BYTE)min(255L,max(0L,(long)c.rgbRed + ((er*7)/16)));
    c.rgbGreen = (BYTE)min(255L,max(0L,(long)c.rgbGreen + ((eg*7)/16)));
    c.rgbBlue = (BYTE)min(255L,max(0L,(long)c.rgbBlue + ((eb*7)/16)));
    SetPixelColor(x+1,y,c);
    int coeff;
    for(int i=-1; i<2; i++){
    switch(i){
    case -1:
    coeff=2; break;
    case 0:
    coeff=4; break;
    case 1:
    coeff=1; break;
    }
    c = GetPixelColor(x+i,y+1);
    c.rgbRed = (BYTE)min(255L,max(0L,(long)c.rgbRed + ((er * coeff)/16)));
    c.rgbGreen = (BYTE)min(255L,max(0L,(long)c.rgbGreen + ((eg * coeff)/16)));
    c.rgbBlue = (BYTE)min(255L,max(0L,(long)c.rgbBlue + ((eb * coeff)/16)));
    SetPixelColor(x+i,y+1,c);
    }
    }
    }
    } if (head.biBitCount==1){
    tmp.SetPaletteColor(0,0,0,0);
    tmp.SetPaletteColor(1,255,255,255);
    } Transfer(tmp);
    return true;
    }
      

  3.   


    ////////////////////////////////////////////////////////////////////////////////
    bool CxImage::IncreaseBpp(DWORD nbit)
    {
    if (!pDib) return false;
    switch (nbit){
    case 4:
    {
    if (head.biBitCount==4) return true;
    if (head.biBitCount>4) return false; CxImage tmp;
    tmp.CopyInfo(*this);
    tmp.Create(head.biWidth,head.biHeight,4,info.dwType);
    tmp.SetPalette(GetPalette(),GetNumColors());
    #if CXIMAGE_SUPPORT_SELECTION
    tmp.SelectionCopy(*this);
    #endif //CXIMAGE_SUPPORT_SELECTION#if CXIMAGE_SUPPORT_ALPHA
    tmp.AlphaCopy(*this);
    #endif //CXIMAGE_SUPPORT_ALPHA for (long y=0;y<head.biHeight;y++){
    if (info.nEscape) break;
    for (long x=0;x<head.biWidth;x++){
    tmp.SetPixelIndex(x,y,GetPixelIndex(x,y));
    }
    }
    Transfer(tmp);
    return true;
    }
    case 8:
    {
    if (head.biBitCount==8) return true;
    if (head.biBitCount>8) return false; CxImage tmp;
    tmp.CopyInfo(*this);
    tmp.Create(head.biWidth,head.biHeight,8,info.dwType);
    tmp.SetPalette(GetPalette(),GetNumColors());#if CXIMAGE_SUPPORT_SELECTION
    tmp.SelectionCopy(*this);
    #endif //CXIMAGE_SUPPORT_SELECTION#if CXIMAGE_SUPPORT_ALPHA
    tmp.AlphaCopy(*this);
    #endif //CXIMAGE_SUPPORT_ALPHA for (long y=0;y<head.biHeight;y++){
    if (info.nEscape) break;
    for (long x=0;x<head.biWidth;x++){
    tmp.SetPixelIndex(x,y,GetPixelIndex(x,y));
    }
    }
    Transfer(tmp);
    return true;
    }
    case 24:
    {
    if (head.biBitCount==24) return true;
    if (head.biBitCount>24) return false; CxImage tmp;
    tmp.CopyInfo(*this);
    tmp.Create(head.biWidth,head.biHeight,24,info.dwType);#if CXIMAGE_SUPPORT_SELECTION
    tmp.SelectionCopy(*this);
    #endif //CXIMAGE_SUPPORT_SELECTION#if CXIMAGE_SUPPORT_ALPHA
    tmp.AlphaCopy(*this);
    if (AlphaPaletteIsValid() && !AlphaIsValid()) tmp.AlphaCreate();
    #endif //CXIMAGE_SUPPORT_ALPHA for (long y=0;y<head.biHeight;y++){
    if (info.nEscape) break;
    for (long x=0;x<head.biWidth;x++){
    tmp.SetPixelColor(x,y,GetPixelColor(x,y),true);
    }
    }
    Transfer(tmp);
    return true;
    }
    }
    return false;
    }
    ////////////////////////////////////////////////////////////////////////////////
    bool CxImage::Dither(long method)
    {
    if (!pDib) return false;
    if (head.biBitCount == 1) return true;

    switch (method){
    case 1:
    {
    // Multi-Level Ordered-Dithering by Kenny Hoff (Oct. 12, 1995)
    #define NumRows 4
    #define NumCols 4
    #define NumIntensityLevels 2
    #define NumRowsLessOne (NumRows-1)
    #define NumColsLessOne (NumCols-1)
    #define RowsXCols (NumRows*NumCols)
    #define MaxIntensityVal 255
    #define MaxDitherIntensityVal (NumRows*NumCols*(NumIntensityLevels-1)) int DitherMatrix[NumRows][NumCols] = {{0,8,2,10}, {12,4,14,6}, {3,11,1,9}, {15,7,13,5} };

    unsigned char Intensity[NumIntensityLevels] = { 0,1 };                       // 2 LEVELS B/W
    //unsigned char Intensity[NumIntensityLevels] = { 0,255 };                       // 2 LEVELS
    //unsigned char Intensity[NumIntensityLevels] = { 0,127,255 };                   // 3 LEVELS
    //unsigned char Intensity[NumIntensityLevels] = { 0,85,170,255 };                // 4 LEVELS
    //unsigned char Intensity[NumIntensityLevels] = { 0,63,127,191,255 };            // 5 LEVELS
    //unsigned char Intensity[NumIntensityLevels] = { 0,51,102,153,204,255 };        // 6 LEVELS
    //unsigned char Intensity[NumIntensityLevels] = { 0,42,85,127,170,213,255 };     // 7 LEVELS
    //unsigned char Intensity[NumIntensityLevels] = { 0,36,73,109,145,182,219,255 }; // 8 LEVELS
    int DitherIntensity, DitherMatrixIntensity, Offset, DeviceIntensity;
    unsigned char DitherValue;
      
    GrayScale(); CxImage tmp(head.biWidth,head.biHeight,1,info.dwType);#if CXIMAGE_SUPPORT_SELECTION
    tmp.SelectionCopy(*this);
    #endif //CXIMAGE_SUPPORT_SELECTION#if CXIMAGE_SUPPORT_ALPHA
    tmp.AlphaCopy(*this);
    #endif //CXIMAGE_SUPPORT_ALPHA for (long y=0;y<head.biHeight;y++){
    info.nProgress = (long)(100*y/head.biHeight);
    if (info.nEscape) break;
    for (long x=0;x<head.biWidth;x++){ DeviceIntensity = GetPixelIndex(x,y);
    DitherIntensity = DeviceIntensity*MaxDitherIntensityVal/MaxIntensityVal;
    DitherMatrixIntensity = DitherIntensity % RowsXCols;
    Offset = DitherIntensity / RowsXCols;
    if (DitherMatrix[y&NumRowsLessOne][x&NumColsLessOne] < DitherMatrixIntensity)
    DitherValue = Intensity[1+Offset];
    else
    DitherValue = Intensity[0+Offset]; tmp.SetPixelIndex(x,y,DitherValue);
    }
    }
    tmp.SetPaletteColor(0,0,0,0);
    tmp.SetPaletteColor(1,255,255,255);
    Transfer(tmp);
    break;
    }
    default:
    {
    // Floyd-Steinberg error diffusion (Thanks to Steve McMahon)
    long error,nlevel,coeff;
    BYTE level; GrayScale(); CxImage tmp(head.biWidth,head.biHeight,1,info.dwType);#if CXIMAGE_SUPPORT_SELECTION
    tmp.SelectionCopy(*this);
    #endif //CXIMAGE_SUPPORT_SELECTION#if CXIMAGE_SUPPORT_ALPHA
    tmp.AlphaCopy(*this);
    #endif //CXIMAGE_SUPPORT_ALPHA for (long y=0;y<head.biHeight;y++){
    info.nProgress = (long)(100*y/head.biHeight);
    if (info.nEscape) break;
    for (long x=0;x<head.biWidth;x++){ level=GetPixelIndex(x,y);
    if (level > 128){
    tmp.SetPixelIndex(x,y,1);
    error = level-255;
    } else {
    tmp.SetPixelIndex(x,y,0);
    error = level;
    } nlevel = GetPixelIndex(x+1,y) + (error * 7)/16;
    level = (BYTE)min(255,max(0,(int)nlevel));
    SetPixelIndex(x+1,y,level);
    for(int i=-1; i<2; i++){
    switch(i){
    case -1:
    coeff=3; break;
    case 0:
    coeff=5; break;
    case 1:
    coeff=1; break;
    }
    nlevel = GetPixelIndex(x+i,y+1) + (error * coeff)/16;
    level = (BYTE)min(255,max(0,(int)nlevel));
    SetPixelIndex(x+i,y+1,level);
    }
    }
    }
    tmp.SetPaletteColor(0,0,0,0);
    tmp.SetPaletteColor(1,255,255,255);
    Transfer(tmp);
    }
    }
    return true;
    }
    ////////////////////////////////////////////////////////////////////////////////这是从CXImage中找出来的,就是实现不同位深之间的转换。
    自己整理一下。
      

  4.   

    24位位图是最简单的bmp格式了,你通过LoadImage可以把任何bmp读如HBITMAP,然后就是把HBITMAP存成24位位图
      

  5.   

    CBitmap bitmap;
    HANDLE h=::LoadImage(0,"f:\\abc.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
    bitmap.Attach(h);
    CFile file("F:\\abc1.bmp",CFile::modeCreate|CFile::modeWrite); BITMAP size;
    bitmap.GetBitmap(&size);
    int iHeight=size.bmHeight;
    int iWidth=size.bmWidth;
    int WIDTHBYTES;
    unsigned char * pBitBuf=NULL; WIDTHBYTES=(iWidth*3+3)/4*4;
    pBitBuf=(unsigned char *)malloc(WIDTHBYTES*iHeight); BITMAPFILEHEADER BitFileHead;
    BITMAPINFOHEADER BitInfoHead;
    BitInfoHead.biHeight=iHeight;
    BitInfoHead.biWidth=iWidth;
    BitInfoHead.biSizeImage=WIDTHBYTES*iHeight;
    BitInfoHead.biSize          = sizeof(BITMAPINFOHEADER);
    BitInfoHead.biPlanes        = 1;
    BitInfoHead.biBitCount      = 24;
    BitInfoHead.biCompression   = BI_RGB;
    BitInfoHead.biXPelsPerMeter = 2952; // 75 DPI 
    BitInfoHead.biYPelsPerMeter = 2952; // 75 DPI 
    BitInfoHead.biClrUsed       = 0;
    BitInfoHead.biClrImportant  = 0;

    BitFileHead.bfType      = 'MB'; // Non-portable... sigh 
    BitFileHead.bfSize      = BitInfoHead.biSizeImage+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
    BitFileHead.bfReserved1 = 0;
    BitFileHead.bfReserved2 = 0;
    BitFileHead.bfOffBits   =sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); BITMAPINFO mapinfo;
    mapinfo.bmiHeader=BitInfoHead;
    // mapinfo.bmiColors HDC hdc = CreateIC (TEXT("DISPLAY"), NULL, NULL, NULL) ;
    ::GetDIBits (hdc, (HBITMAP)h,0, iHeight, pBitBuf, &mapinfo, DIB_RGB_COLORS) ;
    file.Write(&BitFileHead,sizeof(BITMAPFILEHEADER));
    file.Write(&BitInfoHead,sizeof(BITMAPINFOHEADER));
    file.Write(pBitBuf,WIDTHBYTES*iHeight); free(pBitBuf);

    file.Close();
      

  6.   

    :ConvertToTrueColorImage(BITMAPINFOHEADER bitInfo,HBITMAP hBitmap)
    {
    HDC  hdc;  
    CDC dc;
        int iBits; 
    WORD wBitCount;   
    DWORD dwBmBitsSize, dwDIBSize, dwWritten;
    BITMAPFILEHEADER bmfHdr; 
    BITMAPINFOHEADER  bi; 
    LPBITMAPINFOHEADER lpbi;
    HANDLE hDib;  
    try
    {

    dc.CreateDC("DISPLAY", "DISPLAY", 0, 0);  
    hdc = dc.m_hDC;
    BITMAP BMP;
    wBitCount = 24;
    bi.biSize            = sizeof(BITMAPINFOHEADER);
    bi.biWidth           = abs(bitInfo.biWidth);
    bi.biHeight          = abs(bitInfo.biHeight);
    bi.biPlanes          = 1;
    bi.biBitCount         = wBitCount;
    bi.biCompression      = BI_RGB;
    bi.biSizeImage        = bitInfo.biSizeImage;
    bi.biXPelsPerMeter     = bitInfo.biXPelsPerMeter;
    bi.biYPelsPerMeter     = bitInfo.biYPelsPerMeter;
    bi.biClrUsed         = 0;
    bi.biClrImportant      = 0;
    dwBmBitsSize = ((bi.biWidth *wBitCount+31)/32)* 4*bi.biHeight ;
    hDib  = GlobalAlloc(GHND,dwBmBitsSize+sizeof(BITMAPINFOHEADER));
    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
    *lpbi = bi; // CClientDC dc(this);

    GetDIBits(hdc, hBitmap, 0, (UINT) bi.biHeight,(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
    ,(BITMAPINFO *)lpbi, DIB_RGB_COLORS);

    bmfHdr.bfType = 0x4D42;  
    dwDIBSize    =  sizeof(BITMAPINFOHEADER)+ dwBmBitsSize;  
    bmfHdr.bfSize = dwDIBSize;
    bmfHdr.bfReserved1 = 0;
    bmfHdr.bfReserved2 = 0;
    bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER);
    if(m_Data!=NULL)
    delete []m_Data;
    m_Data = new unsigned char[dwBmBitsSize];
    unsigned char *data = (unsigned char *)lpbi;
    memcpy(m_Data,&data[sizeof(BITMAPINFOHEADER)],dwBmBitsSize);

    if(m_FileHeaderData!=NULL)
    delete []m_FileHeaderData;
    m_FileHeaderData = new unsigned char[sizeof(BITMAPFILEHEADER)];
    memcpy(m_FileHeaderData,&bmfHdr,sizeof(BITMAPFILEHEADER));
    if(m_InfoHeaderData!=NULL)
    delete []m_InfoHeaderData;
    m_InfoHeaderData = new unsigned char[sizeof(BITMAPINFOHEADER)];
    memcpy(m_InfoHeaderData,&lpbi,sizeof(BITMAPINFOHEADER)); m_Depth = 24;
    m_BMPWidth  = bi.biWidth ;
    m_BMPHeight = bi.biHeight;
    m_Channel  = m_Depth/8;
    m_BytesPerLine = dwBmBitsSize/m_BMPHeight;
    BITMAPINFO  m_bmi;
    ZeroMemory( &m_bmi, sizeof( BITMAPINFO ) );
    m_bmi.bmiHeader= *lpbi;
    HBITMAP hBit = CreateDIBitmap(hdc,lpbi,CBM_INIT,m_Data,&m_bmi,DIB_RGB_COLORS|DIB_PAL_COLORS);
    if(m_hBitmap!=NULL)
    DeleteObject(m_hBitmap);
    m_hBitmap = (HBITMAP)CopyImage(hBit,IMAGE_BITMAP,m_BMPWidth,m_BMPHeight,LR_CREATEDIBSECTION);
    GlobalUnlock(hDib);
    GlobalFree(hDib);
    DeleteObject(hBit);
    }
    catch(...)
    {
    return _UNEXPECTED_ERROR;
    }
    return _NO_ERR;
    }