标题://求大神指点什么地方出错了
取消只看楼主
求学13
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2013-4-3
结帖率:0
已结贴  问题点数:20 回复次数:0 
//求大神指点什么地方出错了
class ImageDib{
   
public:
   
   
    char * m_pImgDate;                             //图像数据指针
    LPRGBQUAD m_lpColorTable;                     //图像颜色表指针
    int m_nBitCount;                             //每像素占的位数
   
private:
   
   
    LPBYTE m_lpDib;                                    //指向dip的指针
    HPALETTE m_hPalette;                             //逻辑调色板句柄
    int m_nColorTableLength;                         //颜色表长度(多少个表项)
   
   
public:
   
    int m_imgWidth;                                     //图像的宽,以像素为单位
    int m_imgHeight;                                 //图像的高,以像素为单位
    LPBITMAPINFOHEADER m_lpBmpInfpHead;                //图像信息头指针
    //成员函数
   
public:
   
    ImageDib();                                        //构造函数
    ~ImageDib();                                    //析构函数
   
    BOOL Read(LPCTSTR lpszPathName);                //dip读函数
    BOOL Write(LPCTSTR lpszPathName);                //dip写函数
    int ComputeColorTabalLength(int nBitCount);        //计算指针长度
    BOOL Draw(CDC* pDC,CPoint origin,CSize size);    //图形绘制
    CSize GetDimensions();                            //读取像素维数
    void ReplaceDip(CSize size,int nBitCount,LPRGBQUAD lpColorTable,
        char pImgData);                                //用新的数据替换dip
   
   
private:
   
    void MakePalette();                                //创建逻辑调色板
    void Empty();                                    //清理空间
   
   
};


ImageDib::ImageDib()
{
    m_lpDib=NULL;                            // 初始化m-lpdip为空
    m_lpColorTable=NULL;                    // 图像表指针为空
    m_pImgDate=NULL;                        // 图像数据指针为空
    m_lpBmpInfpHead=NULL;                    // 图像信息头为空
    m_hPalette=NULL;                        // 调色板为空
    return 0;
}
ImageDib::~ImageDib()
{
    //释放m-lpdip所指向的空间
    if (m_lpDib !=NULL)
    {

        delete  []m_lpDib;
    }
   
    //如果有调色板,释放调色板缓冲区
    if (m_hPalette !=NULL)
    {

        delete [] m_hPalette;
    }

}

ImageDib::ImageDib(CSize size , int nBitcount ,LPRGBQUAD lpColorTable,char * pImgData){

    //如果没有位图像数据传入,我们认为空的dip,此时不分配dib内存
    if (pImgData==NULL)
    {

        m_lpDib=NULL;                            //m-lpdip为空
        m_lpColorTable=NULL;                    //图像表指针为空
        m_pImgDate=NULL;                        //图像数据指针为空
        m_lpBmpInfpHead=NULL;                    //图像信息头为空
        m_hPalette=NULL;                        //调色板为空

    }

    else{//如果有位图像数据传入
         //则图像的宽,高,每像素位数等成员变量赋值

        m_imgWidth=size.cx;
        m_imgHeight=size.cy;
        m_nBitCount=nBitcount;

        //根据每像素位数,计算颜色长度

        m_nColorTableLength=ComputeColorTabalLength(nBitcount);

        //每行像素所占的字节数,必须扩展成4的倍数
        int lineByte=(m_imgWidth*nBitcount/8+3)/4*4;

        //位图数据缓冲区的大小(图像大小)
        int imgBufSize=m_imgHeight*lineByte;

        //为m_lpDip一次性分配内存,生成DIB结构
        m_lpDib=new BYTE[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableLength+imgBufSize];

        //填写BITMAPINFOHEADER结构
        m_lpBmpInfpHead=(LPBITMAPINFOHEADER) m_lpDib;
        m_lpBmpInfpHead->biSize=sizeof(BITMAPINFOHEADER);
        m_lpBmpInfpHead->biWidth=m_imgWidth;
        m_lpBmpInfpHead->biHeight=m_imgHeight;
        m_lpBmpInfpHead->biPlanes=1;             //目标设备平面数设置为一
        m_lpBmpInfpHead->biBitCount=m_nBitCount;
        m_lpBmpInfpHead->biCompression=BI_RGB;   //压缩类型,不压缩为为0
        m_lpBmpInfpHead->biSizeImage=0;            //压缩图像大小的字节数,费压缩图像为0
        m_lpBmpInfpHead->biXPelsPerMeter=0;        //水平分辨率
        m_lpBmpInfpHead->biYPelsPerMeter=0;        //垂直分辨率
        m_lpBmpInfpHead->biClrUsed=m_nColorTableLength;//使用颜色的彩数
        m_lpBmpInfpHead->biClrImportant=m_nColorTableLength;  //重要色彩数,0表示都重要;
        //调色板句柄初始化为空,有颜色时,makepalette()函数要生成新的调色板
        m_hPalette = NULL;
        //如果有颜色表,则将颜色表复制进dib的颜色表位置
        if (m_nColorTableLength ! = 0)
        {

            //m_lpColorTable指向dib颜色表的起始位置
            m_lpColorTable = (LPRGBQUAD) (m_lpDib+sizeof(BITMAPINFOHEADER));
            //颜色表复制
            memcpy(m_lpColorTable,lpColorTable,sizeof(RGBQUAD)*m_nColorTableLength);
            //创建逻辑调色板
            MakePalette();
        }
        //m_pImgDate指向dib位图数据起始位置
        m_pImgDate=(LPBYTE)m_lpDib+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableLength;
        //复制图像数据进dib位图数据区
        memcpy(m_pImgDate,pImgData,imgBufSize);

    }


}

BOOL ImageDib::Read(LPCTSTR lpszPathname)
{

    //读模式打开文件
    CFile file;
    if(!file.Open(lpszPathname,CFile::modeRead|CFile::shareDenyWrite))
        return FALSE;
    BITMAPINFOHEADER bmfh;
    //读取    BITMAPINFOHEADER 结构变量bmfh中
    int nCount=file.Read((LPVOID)&bmfh,sizeof(BITMAPFILEHEADER));
    //为m_lpDip分配空间,读取dib进内存
    if(m_lpDib!=NULL)
        delete []m_lpDib;
    m_lpDib=new BYTE[file.GetLength()]-sizeof(BITMAPFILEHEADER);
    file.Read(m_lpDib,file.GetLength() -sizeof(BITMAPFILEHEADER));
    //m_lpBmpInfpHead位置为 m_lpDib起始位置
    m_lpBmpInfpHead= (LPBITMAPINFOHEADER)m_lpDib;
    //为成员变量赋值
    m_imgWidth=m_lpBmpInfpHead->biWidth;
    m_imgHeight=m_lpBmpInfpHead->biHeight;
    m_nBitCount=m_lpBmpInfpHead->biBitCount;
    //计算颜色长度
    m_nColorTableLength=ComputeColorTabalLength(m_lpBmpInfpHead->biBitCount);
    //如果有颜色表,则创建逻辑调色板
    m_hPalette = NULL;
    if (m_nColorTableLength!=0)
    {

        (LPRGBQUAD)(m_lpDib+sizeof(BITMAPINFOHEADER));
        MakePalette();
    }
   
    //m_pImgDate指向dib的位图位图数据起始位置
    m_pImgDate=(LPBYTE)m_lpDib+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableLength;
    return TRUE;
}
   
BOOL ImageDib::Write(LPCTSTR lpszPathName){
    //以写模式打开文件
    CFile file;
    if (!file.Open(lpszPathName,CFile::modeCreate|CFile::modeReadWrite|CFile::shareExclusive))
    {
        return FALSE;
    }
    //填写文件头结构
    BITMAPINFOHEADER bmfh;
    bmfh.bfType=0x4d42;  //'bm'
    bmfh.biSize=0;
    bmfh.bfReserverd1=bmfh.bfReserver2 = 0;
    bmfh.bfoffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableLength;
    try
    {
        //文件头结构写进文件
        file.Write((LPVOID) & bmfh,sizeof(BITMAPFILEHEADER));

        //文件信息头结构写进文件
        file.Write(m_lpBmpInfpHead,sizeof(BITMAPINFOHEADER));

        //如果有颜色表的话,颜色表写进文件
        if (m_nColorTableLength!=0)
        {
            file.Write(m_lpColorTable,sizeof(RGBQUAD)*m_nColorTableLength);
        }

        //位图数据写进文件
        int imgBuffSize = (m_imgWidth*m_nBitCount/8+3)/4*4*m_imgHeight;
        file.Write(m_pImgDate,imgBuffSize);
    }
    catch (CException* pe)
    {
        pe->Delete();
        AfxMessageBox("write error");
        return FALSE;
    }

    //函数返回
    return TRUE;
}

void ImageDib::MakePalette(){

    //如果颜色表长度为0,则不创建逻辑调色板
    if (m_nColorTableLength==0)
    {
        return ;
    }
    //删除旧的逻辑调色板句柄
    if (m_hPalette!=NULL)::DeleteObject(m_hPalette);
    //申请空间,根据颜色表生成LOGPALETTE结构
    LPLOGPALETTE pLogPal = (LPLOGPALETTE) new char[2*sizeof(WORD)+m_nColorTableLength*sizeof(PALETTEENTRY)];
    pLogPal->palVersion=0x30;
    pLogPal->palNumEntries = m_nColorTableLength;
    LPRGBQUAD m_lpDibQuad = (LPRGBQUAD) m_lpColorTable;
    for(int i = 0 ; i<m_nColorTableLength;i++){

        pLogPal->palPalEntry[i].peRed=m_lpDibQuad->rgbRed;
        pLogPal->palPalEntry[i].peBlue=m_lpDibQuad->rgbBlue;
        pLogPal->palPalEntry[i].peGreen=m_lpDibQuad->rgbGreen;
        pLogPal->palPalEntry[i].peFlags=0;
        m_lpDibQuad++
    }

    //创建逻辑调色板
    m_hPalette=::CreatePalette(pLogPal);
    //释放空间
    delete pLogPal;
}
int ImageDib::ComputeColorTabalLength(int nBitCount){

    int colorTableLength;
    switch (nBitCount)
    {

    case 1:
        colorTableLength=2;
        break;
    case 4:
        colorTableLength=16;
        break;
    case 8:
        colorTableLength=256;
        break;
    case 16:
    case 24:
    case 32:
        colorTableLength=0;
        break;
    default:
        ASSERT(FALSE);
    }
    ASSERT((colorTableLength>=0)&&(colorTableLength<=256));
    return colorTableLength;
}

BOOL ImageDib::Draw(CDC* pDC,CPoint origin,CSize size )
{

    HPALETTE hOldPal =NULL;            //旧的调色板句柄
    if (m_lpDib==NULL)                //如果dib为空,则返回0
    {

        return FALSE;
    }
    if (m_hPalette !=NULL)            //如果dib有调色板
    {                                 //将调色板选进设备环境中

        hOldPal=::SelectPalette(pDC->GetSafeHdc());
        pDC->RealizePalette();
    }
    pDC->SetStretchBltMode(COLORONCOLOR);  //设置位图伸缩模式
    //将dib在pdc所指的设备上进行显示
    ::StretchDIBits(pDC->GetSafeHdc(),origin.x,origin.y,size.cx,size.cy,0,0,
                    m_lpBmpInfpHead->biWidth,m_lpBmpInfpHead->biHeight,
                    m_pImgDate,(LPBITMAPINFO)m_lpBmpInfpHead,DIB_RGB_COLORS,SRCCOPY);
    if (hOldPal!=NULL)
    {//恢复旧的调色板

        ::SelectPalette(pDC->GetSafeHdc(),hOldPal,TRUE);
    }
    return TRUE;
}

CSize ImageDib::GetDimensions(){

    if (m_lpDib==NULL)
    {

        return CSize(0,0);
    }

    return CSize(m_imgWidth,m_imgHeight);

}
    void ImageDib::Empty(){  //释放dib内存缓冲区

        if (m_lpDib!=NULL)
        {

            delete [] m_lpDib;
            m_lpDib=NULL;                            //初始化m-lpdip为空
            m_lpColorTable=NULL;                    //图像表指针为空
            m_pImgDate=NULL;                        //图像数据指针为空
            m_lpBmpInfpHead=NULL;                    //图像信息头为空
            m_hPalette=NULL;                        //调色板为空
        }
        //释放逻辑调色板缓冲区
        if (m_hPalette!=NULL)
        {

            ::DeleteObject(m_hPalette);
            m_hPalette=NULL;
        }
    }

    void ImageDib::ReplaceDip(CSize size,int nBitCount,LPRGBQUAD lpColorTable,
        char pImgData){

        //释放原dib所占空间
        Empty();
        //成员变量赋值
        m_imgWidth=size.cx;
        m_imgHeight=size.cy;
        m_nBitCount=nBitcount;
        //计算颜色表的长度
        m_nColorTableLength=ComputeColorTabalLength(nBitcount);
        //每行像素所占字节数,扩展成4的倍数
        int lineByte =(m_imgWidth*nBitCount/8+3)/4*4;

        
        //位图数据缓冲区的大小(图像大小)
        int imgBufSize=m_imgHeight*lineByte;
        
        //为m_lpDip重新分配内存,存放新的DIB结构
        m_lpDib=new BYTE[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableLength+imgBufSize];
        
        //填写BITMAPINFOHEADER结构
        m_lpBmpInfpHead=(LPBITMAPINFOHEADER) m_lpDib;
        m_lpBmpInfpHead->biSize=sizeof(BITMAPINFOHEADER);
        m_lpBmpInfpHead->biWidth=m_imgWidth;
        m_lpBmpInfpHead->biHeight=m_imgHeight;
        m_lpBmpInfpHead->biPlanes=1;             //目标设备平面数设置为一
        m_lpBmpInfpHead->biBitCount=m_nBitCount;
        m_lpBmpInfpHead->biCompression=BI_RGB;   //压缩类型,不压缩为为0
        m_lpBmpInfpHead->biSizeImage=0;            //压缩图像大小的字节数,费压缩图像为0
        m_lpBmpInfpHead->biXPelsPerMeter=0;        //水平分辨率
        m_lpBmpInfpHead->biYPelsPerMeter=0;        //垂直分辨率
        m_lpBmpInfpHead->biClrUsed=m_nColorTableLength;//使用颜色的彩数
        m_lpBmpInfpHead->biClrImportant=m_nColorTableLength;  //重要色彩数,0表示都重要;
        //调色板置空
        m_hPalette = NULL;
        //如果有颜色表,则将颜色表复制进dib的颜色表位置,并创建逻辑调色板
        if (m_nColorTableLength ! = 0)
        {
            
            //m_lpColorTable指向dib颜色表的起始位置
            m_lpColorTable = (LPRGBQUAD) (m_lpDib+sizeof(BITMAPINFOHEADER));
            //颜色表复制
            memcpy(m_lpColorTable,lpColorTable,sizeof(RGBQUAD)*m_nColorTableLength);
            //创建逻辑调色板
            MakePalette();
        }
        //m_pImgDate指向dib位图数据起始位置
        m_pImgDate=(LPBYTE)m_lpDib+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableLength;
        //复制图像数据进dib位图数据区
        memcpy(m_pImgDate,pImgData,imgBufSize);

    }
搜索更多相关主题的帖子: 图像 private public 调色板 
2013-05-21 15:09



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-407631-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.111667 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved