我有个DIBtopcx256的程序,求高人帮我改成BMP2PCX的,最好不限制在256上,谢谢了
我的E-MAIL:[email protected]
下面是头文件 //dibapi.h#ifndef _INC_DIBAPI
#define _INC_DIBAPI// DIB句柄
DECLARE_HANDLE(HDIB);// DIB常量
#define PALVERSION   0x300/* DIB宏 */// 判断是否是Win 3.0的DIB
#define IS_WIN30_DIB(lpbi)  ((*(LPDWORD)(lpbi)) == sizeof(BITMAPINFOHEADER))// 计算矩形区域的宽度
#define RECTWIDTH(lpRect)     ((lpRect)->right - (lpRect)->left)// 计算矩形区域的高度
#define RECTHEIGHT(lpRect)    ((lpRect)->bottom - (lpRect)->top)// 在计算图像大小时,采用公式:biSizeImage = biWidth' × biHeight。
// 是biWidth',而不是biWidth,这里的biWidth'必须是4的整倍数,表示
// 大于或等于biWidth的,离4最近的整倍数。WIDTHBYTES就是用来计算
// biWidth'
#define WIDTHBYTES(bits)    (((bits) + 31) / 32 * 4)// PCX文件头结构
typedef struct{
 BYTE bManufacturer;
 BYTE bVersion;
 BYTE bEncoding;
 BYTE bBpp;
 WORD wLeft;
 WORD wTop;
 WORD wRight;
 WORD wBottom;
 WORD wXResolution;
 WORD wYResolution;
 BYTE bPalette[48];
 BYTE bReserved;
 BYTE bPlanes;
 WORD wLineBytes;
 WORD wPaletteType;
 WORD wSrcWidth;
 WORD wSrcDepth;
 BYTE bFiller[54];
} PCXHEADER;// 函数原型
BOOL      WINAPI  PaintDIB (HDC, LPRECT, HDIB, LPRECT, CPalette* pPal);
BOOL      WINAPI  CreateDIBPalette(HDIB hDIB, CPalette* cPal);
LPSTR     WINAPI  FindDIBBits (LPSTR lpbi);
DWORD     WINAPI  DIBWidth (LPSTR lpDIB);
DWORD     WINAPI  DIBHeight (LPSTR lpDIB);
WORD      WINAPI  PaletteSize (LPSTR lpbi);
WORD      WINAPI  DIBNumColors (LPSTR lpbi);
WORD   WINAPI  DIBBitCount(LPSTR lpbi);
HGLOBAL   WINAPI  CopyHandle (HGLOBAL h);BOOL      WINAPI  SaveDIB (HDIB hDib, CFile& file);
HDIB      WINAPI  ReadDIBFile(CFile& file);BOOL      WINAPI  DIBToPCX256(LPSTR lpDIB, CFile& file);
HDIB      WINAPI  ReadPCX256(CFile& file);#endif //!_INC_DIBAPI

解决方案 »

  1.   

    下面是DIBAPI.CPP文件
    /*************************************************************************
     *
     * 函数名称:
     *   DIBToPCX256()
     *
     * 参数:
     *   LPSTR lpDIB        - 指向DIB对象的指针
     *   CFile& file        - 要保存的文件
     *
     * 返回值:
     *   BOOL               - 成功返回True,否则返回False。
     *
     * 说明:
     *   该函数将指定的256色DIB对象保存为256色PCX文件。
     *
     *************************************************************************/
    BOOL WINAPI DIBToPCX256(LPSTR lpDIB, CFile& file)
    {
    // 循环变量
    LONG i;
    LONG j;

    // DIB高度
    WORD wHeight;

    // DIB宽度
    WORD wWidth;

    // 中间变量
    BYTE bChar1;
    BYTE bChar2;

    // 指向源图像象素的指针
    BYTE * lpSrc;

    // 指向编码后图像数据的指针
    BYTE * lpDst;

    // 图像每行的字节数
    LONG lLineBytes;

    // 重复像素计数
    int iCount;

    // 缓冲区已使用的字节数
    DWORD dwBuffUsed;

    // 指向DIB象素指针
    LPSTR   lpDIBBits;

    // 获取DIB高度
    wHeight = (WORD) DIBHeight(lpDIB);

    // 获取DIB宽度
    wWidth  = (WORD) DIBWidth(lpDIB);

    // 找到DIB图像象素起始位置

     *  函数名称: FindDIBBits() //下面用到了
     *
     * 参数:
     *   LPSTR lpbi         - 指向DIB对象的指针
     *
     * 返回值:
     *   LPSTR              - 指向DIB图像象素起始位置
     *
     * 说明:
     *   该函数计算DIB中图像象素的起始位置,并返回指向它的指针。
     
     LPSTR WINAPI FindDIBBits(LPSTR lpbi)
    {
    return (lpbi + *(LPDWORD)lpbi + ::PaletteSize(lpbi));
    }
             lpDIBBits = FindDIBBits(lpDIB);
            // 计算图像每行的字节数
    lLineBytes = WIDTHBYTES(wWidth * 8);


    //*************************************************************************
    // PCX文件头
    PCXHEADER pcxHdr;

    // 给文件头赋值

    // PCX标识码
    pcxHdr.bManufacturer = 0x0A;

    // PCX版本号
    pcxHdr.bVersion = 5;

    // PCX编码方式(1表示RLE编码)
    pcxHdr.bEncoding = 1;

    // 像素位数(256色为8位)
    pcxHdr.bBpp = 8;

    // 图像相对于屏幕的左上角X坐标(以像素为单位)
    pcxHdr.wLeft = 0;

    // 图像相对于屏幕的左上角Y坐标(以像素为单位)
    pcxHdr.wTop = 0;

    // 图像相对于屏幕的右下角X坐标(以像素为单位)
    pcxHdr.wRight = wWidth - 1;

    // 图像相对于屏幕的右下角Y坐标(以像素为单位)
    pcxHdr.wBottom = wHeight - 1;

    // 图像的水平分辨率
    pcxHdr.wXResolution = wWidth;

    // 图像的垂直分辨率
    pcxHdr.wYResolution = wHeight;

    // 调色板数据(对于256色PCX无意义,直接赋值为0)
    for (i = 0; i < 48; i ++)
    {
    pcxHdr.bPalette[i] = 0;
    }

    // 保留域,设定为0。
    pcxHdr.bReserved = 0;

    // 图像色彩平面数目(对于256色PCX设定为1)。
    pcxHdr.bPlanes = 1;

    // 图像的宽度(字节为单位),必须为偶数。
    // if ((wWidth & 1) == 0)
    // {
    pcxHdr.wLineBytes = wWidth;
    // }
    // else
    // {
    // pcxHdr.wLineBytes = wWidth + 1;
    // }

    // 图像调色板的类型,1表示彩色或者单色图像,2表示图像是灰度图。
    pcxHdr.wPaletteType = 1;

    // 制作该图像的屏幕宽度(像素为单位)
    pcxHdr.wSrcWidth = 0;

    // 制作该图像的屏幕高度(像素为单位)
    pcxHdr.wSrcDepth = 0;

    // 保留域,取值设定为0。
    for (i = 0; i < 54; i ++)
    {
    pcxHdr.bFiller[i] = 0;
    }

    // 写入文件头
    file.Write((LPSTR)&pcxHdr, sizeof(PCXHEADER));
      

  2.   

    // 开始编码

    // 开辟一片缓冲区(2被原始图像大小)以保存编码结果
    lpDst = new BYTE[wHeight * wWidth * 2];

    // 指明当前已经用了多少缓冲区(字节数)
    dwBuffUsed = 0;

    // 每行
    for (i = 0; i < wHeight; i++)
    {
    // 指向DIB第i行,第0个象素的指针
    lpSrc = (BYTE *)lpDIBBits + lLineBytes * (wHeight - 1 - i);

    // 给bChar1赋值
    bChar1 = *lpSrc;

    // 设置iCount为1
    iCount = 1;

    // 剩余列
    for (j = 1; j < wWidth; j ++)
    {
    // 指向DIB第i行,第j个象素的指针
    lpSrc++;

    // 读取下一个像素
    bChar2 = *lpSrc;

    // 判断是否和bChar1相同并且iCount < 63
    if ((bChar1 == bChar2) && (iCount < 63))
    {
    // 相同,计数加1
    iCount ++;

    // 继续读下一个
    }
    else
    {
    // 不同,或者iCount = 63

    // 写入缓冲区
    if ((iCount > 1) || (bChar1 >= 0xC0))
    {
    // 保存码长信息
    lpDst[dwBuffUsed] = iCount | 0xC0;

    // 保存bChar1
    lpDst[dwBuffUsed + 1] = bChar1;

    // 更新dwBuffUsed
    dwBuffUsed += 2;
    }
    else
    {
    // 直接保存该值
    lpDst[dwBuffUsed] = bChar1;

    // 更新dwBuffUsed
    dwBuffUsed ++;
    }

    // 重新给bChar1赋值
    bChar1 = bChar2;

    // 设置iCount为1
    iCount = 1;
    }
    }

    // 保存每行最后一部分编码
    if ((iCount > 1) || (bChar1 >= 0xC0))
    {
    // 保存码长信息
    lpDst[dwBuffUsed] = iCount | 0xC0;

    // 保存bChar1
    lpDst[dwBuffUsed + 1] = bChar1;

    // 更新dwBuffUsed
    dwBuffUsed += 2;
    }
    else
    {
    // 直接保存该值
    lpDst[dwBuffUsed] = bChar1;

    // 更新dwBuffUsed
    dwBuffUsed ++;
    }
    }

    // 写入编码结果
    file.WriteHuge((LPSTR)lpDst, dwBuffUsed);

    // 释放内存
    delete lpDst;

    //**************************************************************************
    // 写入调色板信息

    // 指向BITMAPINFO结构的指针(Win3.0)
    LPBITMAPINFO lpbmi;

    // 指向BITMAPCOREINFO结构的指针
    LPBITMAPCOREINFO lpbmc;

    // 表明是否是Win3.0 DIB的标记
    BOOL bWinStyleDIB;

    // 开辟一片缓冲区以保存调色板
    lpDst = new BYTE[769];

    // 调色板起始字节
    * lpDst = 0x0C;

    // 获取指向BITMAPINFO结构的指针(Win3.0)
    lpbmi = (LPBITMAPINFO)lpDIB;

    // 获取指向BITMAPCOREINFO结构的指针
    lpbmc = (LPBITMAPCOREINFO)lpDIB;

    // 判断是否是WIN3.0的DIB
    bWinStyleDIB = IS_WIN30_DIB(lpDIB);

    // 读取当前DIB调色板
    for (i = 0; i < 256; i ++)
    {
    if (bWinStyleDIB)
    {
    // 读取DIB调色板红色分量
    lpDst[i * 3 + 1] = lpbmi->bmiColors[i].rgbRed;

    // 读取DIB调色板绿色分量
    lpDst[i * 3 + 2] = lpbmi->bmiColors[i].rgbGreen;

    // 读取DIB调色板蓝色分量
    lpDst[i * 3 + 3] = lpbmi->bmiColors[i].rgbBlue;
    }
    else
    {
    // 读取DIB调色板红色分量
    lpDst[i * 3 + 1] = lpbmc->bmciColors[i].rgbtRed;

    // 读取DIB调色板绿色分量
    lpDst[i * 3 + 2] = lpbmc->bmciColors[i].rgbtGreen;

    // 读取DIB调色板蓝色分量
    lpDst[i * 3 + 3] = lpbmc->bmciColors[i].rgbtBlue;
    }
    }

    // 写入调色板信息
    file.Write((LPSTR)lpDst, 769);

    // 返回
    return TRUE;
    }
      

  3.   

    还有BMP文件格式的一些说明:希望有人可以帮我一下,谢谢~~~
    BMP(Bitmap-File)图形文件是Windows采用的图形文件格式,在Windows环境下运行的所有图象处理软件都支持BMP图象文件格式。Windows系统内部各图像绘制操作都是以BMP为基础的。Windows 3.0以前的BMP图文件格式与显示设备有关,因此把这种BMP图象文件格式称为设备相关位图DDB(device-dependent bitmap)文件格式。Windows 3.0以后的BMP图象文件与显示设备无关,因此把这种BMP图象文件格式称为设备无关位图DIB(device-independent bitmap)格式(注:Windows 3.0以后,在系统中仍然存在DDB位图,象BitBlt()这种函数就是基于DDB位图的,只不过如果你想将图像以BMP格式保存到磁盘文件中时,微软极力推荐你以DIB格式保存),目的是为了让Windows能够在任何类型的显示设备上显示所存储的图象。BMP位图文件默认的文件扩展名是BMP或者bmp(有时它也会以.DIB或.RLE作扩展名)。 6.1.2 文件结构
    位图文件可看成由4个部分组成:位图文件头(bitmap-file header)、位图信息头(bitmap-information header)、彩色表(color table)和定义位图的字节阵列,它具有如下所示的形式。 
    位图文件的组成 
     结构名称 
     符号 
     位图文件头(bitmap-file header) BITMAPFILEHEADER bmfh 
    位图信息头(bitmap-information header) BITMAPINFOHEADER bmih 
    彩色表(color table) RGBQUAD aColors[] 
    图象数据阵列字节 BYTE aBitmapBits[] 
    . 位图文件头 
    位图文件头包含有关于文件类型、文件大小、存放位置等信息,在Windows 3.0以上版本的位图文件中用BITMAPFILEHEADER结构来定义: typedef struct tagBITMAPFILEHEADER { /* bmfh */ 
    UINT bfType;DWORD bfSize; UINT bfReserved1; UINT bfReserved2; DWORD bfOffBits;
    } BITMAPFILEHEADER; 
    其中: 
      bfType
     说明文件的类型.(该值必需是0x4D42,也就是字符'BM'。我们不需要判断OS/2的位图标识,这么做现在来看似乎已经没有什么意义了,而且如果要支持OS/2的位图,程序将变得很繁琐。所以,在此只建议你检察'BM'标识) 
     bfSize
     说明文件的大小,用字节为单位
     bfReserved1
     保留,必须设置为0
     bfReserved2
     保留,必须设置为0
     bfOffBits
     说明从文件头开始到实际的图象数据之间的字节的偏移量。这个参数是非常有用的,因为位图信息头和调色板的长度会根据不同情况而变化,所以你可以用这个偏移值迅速的从文件中读取到位数据。
     
    2. 位图信息头 
    位图信息用BITMAPINFO结构来定义,它由位图信息头(bitmap-information header)和彩色表(color table)组成,前者用BITMAPINFOHEADER结构定义,后者用RGBQUAD结构定义。BITMAPINFO结构具有如下形式: 
    typedef struct tagBITMAPINFO { /* bmi */ 
    BITMAPINFOHEADER bmiHeader;RGBQUAD bmiColors[1];} BITMAPINFO; 
    其中: 
      bmiHeader
     说明BITMAPINFOHEADER结构,其中包含了有关位图的尺寸及位格式等信息
     bmiColors
     说明彩色表RGBQUAD结构的阵列,其中包含索引图像的真实RGB值。
     BITMAPINFOHEADER结构包含有位图文件的大小、压缩类型和颜色格式,其结构定义为: 
    typedef struct tagBITMAPINFOHEADER { /* bmih */ 
    DWORD biSize;     DWORD biCompression; DWORD biSizeImage; 
    LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; 
    DWORD biClrImportant;LONG biWidth;    LONG biHeight; WORD biPlanes; 
    WORD biBitCount; 
    } BITMAPINFOHEADER; 
    biSize
     说明BITMAPINFOHEADER结构所需要的字数。注:这个值并不一定是BITMAPINFOHEADER结构的尺寸,它也可能是sizeof(BITMAPV4HEADER)的值,或是sizeof(BITMAPV5HEADER)的值。这要根据该位图文件的格式版本来决定,不过,就现在的情况来看,绝大多数的BMP图像都是BITMAPINFOHEADER结构的(可能是后两者太新的缘故吧:-)。
    biWidth
     说明图象的宽度,以象素为单位
    biHeight
     说明图象的高度,以象素为单位。注:这个值除了用于描述图像的高度之外,它还有另一个用处,就是指明该图像是倒向的位图,还是正向的位图。如果该值是一个正数,说明图像是倒向的,如果该值是一个负数,则说明图像是正向的。大多数的BMP文件都是倒向的位图,也就是时,高度值是一个正数。(注:当高度值是一个负数时(正向图像),图像将不能被压缩(也就是说biCompression成员将不能是BI_RLE8或BI_RLE4)。
     
    biPlanes
     为目标设备说明位面数,其值将总是被设为1
     
    biBitCount
     说明比特数/象素,其值为1、4、8、16、24、或32
     
    biCompression
     说明图象数据压缩的类型。其值可以是下述值之一: 
     BI_RGB:没有压缩; 
     
     BI_RLE8:每个象素8比特的RLE压缩编码,压缩格式由2字节组成(重复象素计数和颜色索引); 
     
     BI_RLE4:每个象素4比特的RLE压缩编码,压缩格式由2字节组成 
     
     BI_BITFIELDS:每个象素的比特由指定的掩码决定。
     biSizeImage
     说明图象的大小,以字节为单位。当用BI_RGB格式时,可设置为0 
    biXPelsPerMeter
     说明水平分辨率,用象素/米表示 
    biYPelsPerMeter
     说明垂直分辨率,用象素/米表示 
    biClrUsed
     说明位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项) 
    biClrImportant
     说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。
     
      

  4.   

    网上很多库都可以读写PCX,随便找一个看看吧 CXImage / PCL
      

  5.   

    cximage用了 老是出现error like 2019错误,不知道怎么回事啊~~~
    那位高人帮个忙啊~~~~
    急死了~~