MFC数字图像处理24位图转8位图 等四种图像色彩转换方式

一、 实验主要思路和基本操作
本实验主要探究8位图和24位图的颜色转换。8位图具有调色板,调色板中有对应的256种不同的颜色,每种颜色所含的RGB值都不一样。24位图没有调色板,RGB三个颜色分量分别都有0-255可选择,属于真彩色图像。其中,两种不同位数的图形都有彩色图像和灰度图像两种,灰度图像中每个像素的颜色分量,R、G、值都一样。所以本实验核心分为两点:了解颜色的RGB组合和学会调色板的使用

调色板:
主要功能是节省图像字节。8位图像中,图中最多256中颜色,如果采用颜色表,表中每一行记录一种颜色的RGB值,当表示一个像素颜色时,只需要指出该颜色是在第几行,即该颜色在表中的索引值就可以。如,表第0行是255,0,0,为红色时,只需要标明0即可。通过颜色表来表示图像,256种颜色可以用8位表示,一个像素使用1个字节,比原来的每个像素使用3个字节(256+256+256,每个分量一个字节表示)节省很大空间。
24位图由于每个分量中0-255个值都有可能用到,使用调色板反而会增加3个字节的使用调色板空间。所以24位图不使用调色板。

RGB组合:彩色图像三个RGB分量不一定相同,灰色图像三个RGB值相同。0-255的颜色分量可表示各灰度像素的亮度。

基本操作:1.在资源视图中的菜单选项,建立操作菜单,并对菜单定义相应ID。

2.在类视图-属性-事件中,为菜单添加触发操作。

3.在VIEW类中编写程序。

(注:本文所有实验结果图因为无法复制粘贴,重新生成图片较为麻烦,次实验也做较久,故不贴图片显示实验结果。之后实时做的实验都会贴图,望理解。)
二、主要程序

一、8位彩色转换成8位灰度

1.原理:获取原图信息,新建一个调色板,找到该图像对应的像素值,计算该颜色对应的灰度值,通过逐行扫描更换每个像素的颜色索引,更新并保存图像。

细节:1.首先通过lpSrcColorBits=lpSrcDib+sizeof(BITMAPINFOHEADER)获取调色板的指针信息。在新建立的调色板中,利用获取的原图像调色板计算该像素点对应的灰度值。调色板的每一行有3个字节,于是以3为周期,对调色板各个像素信息进行更新。
2.进行逐行扫描时,通过指针先找到数据起始点,逐行对每一行每一列的像素值进行更新。
3.定义像素信息的指针用LPSTR类型。

2.代码实现

//8位彩色转灰度------------------------------------------------------------------------------
void CImgtestView::On88grey()
{
    CImgtestDoc* pDoc=GetDocument();

    long lSrcLineBytes;
    long lSrcWidth;
    long lSrcHeight;
    int lpSrcBitCount;
    LPSTR lpSrcDib;//指向源图像的指针
    LPSTR lpSrcStartBits;//指向数据的指针

    lpSrcDib=(LPSTR)::GlobalLock((HGLOBAL)pDoc->GetHObject());

    if(!lpSrcDib) return;
    if(pDoc->m_dib.GetColorNum(lpSrcDib)!=256)
    {
        AfxMessageBox(L"对不起,不是256色图!");
        ::GlobalUnlock((HGLOBAL)pDoc->GetHObject());
        return;
    }
    lpSrcStartBits=pDoc->m_dib.GetBits(lpSrcDib);
    lSrcWidth=pDoc->m_dib.GetWidth(lpSrcDib);
    lSrcHeight=pDoc->m_dib.GetHeight(lpSrcDib);
    lSrcLineBytes=pDoc->m_dib.GetReqByteWidth(lSrcWidth*8);
    lpSrcBitCount=pDoc->m_dib.GetBitCount(lpSrcDib);
    /////////////////////////////////////////////////////////

    BYTE bMap[256];//灰度映射表
    printf("\n对256色彩色图像变为256级灰度图像\n");


    LPSTR lpSrcColorBits;//指向调色板的指针
    LPSTR lpSrc;// 指向DIB第i行,第j个象素的指针
    lpSrcColorBits=lpSrcDib+sizeof(BITMAPINFOHEADER);

    for(int i=0;i<256;i++)//生成新的调色板,并转换灰度
    {
        // 计算该颜色对应的灰度值g=0.299*r+0.587*g+0.114*b
        int j=0;
        bMap[i]=(BYTE)(0.299 * lpSrcColorBits[j] + 0.587 * lpSrcColorBits[j+1] + 0.114 * lpSrcColorBits[j+2] + 0.5);
        lpSrcColorBits[j]= lpSrcColorBits[j+1]= lpSrcColorBits[j+2]= i;
        lpSrcColorBits=lpSrcColorBits+4;

    }
    // 更换每个象素的颜色索引(即按照灰度映射表换成灰度值)
    // 逐行扫描
    for(int i = 0; i < lSrcHeight; i++)
    {
        //逐列扫描
        for(int j = 0; j < lSrcWidth; j++)
        {
            lpSrc = lpSrcStartBits + lSrcLineBytes * (lSrcHeight - 1 - i) + j;

        *lpSrc =bMap[*lpSrc];// 变换
        }
    }
    pDoc->SetModifiedFlag(TRUE);
    pDoc->UpdateAllViews(NULL);
    ::GlobalUnlock((HGLOBAL)pDoc->GetHObject());

}

3.实验结果

二、24彩色位转24位灰度
1.原理:24位彩色图没有颜色表,所以仅需通过获取位图信息,找到像素点的RGB数据,对像素点进行灰度计算,更新图像,就能完成转换。
细节:1.像素的颜色分量为unsigned char类型。

2.代码实现

//24位转24位灰度------------------------------------------------------------------------------
void CImgtestView::On2424grey()
{
    // TODO: 在此添加命令处理程序代码

    CImgtestDoc* pDoc=GetDocument();

    long lSrcLineBytes;
    long lSrcWidth;
    long lSrcHeight;
    int lpSrcBitCount;
    LPSTR lpSrcDib;//指向源图像的指针
    LPBYTE lpSrcStartBits;//指向数据的指针

    lpSrcDib=(LPSTR)::GlobalLock((HGLOBAL)pDoc->GetHObject());

    if(!lpSrcDib) return;

    lpSrcStartBits=(LPBYTE)pDoc->m_dib.GetBits(lpSrcDib);
    lSrcWidth=pDoc->m_dib.GetWidth(lpSrcDib);
    lSrcHeight=pDoc->m_dib.GetHeight(lpSrcDib);
    lSrcLineBytes=pDoc->m_dib.GetReqByteWidth(lSrcWidth*24);
    lpSrcBitCount=pDoc->m_dib.GetBitCount(lpSrcDib);
    /////////////////////////////////////////////////////

    if (lpSrcBitCount !=24)// 判断是否是8-bpp位图
     {      
        AfxMessageBox(L"对不起,不是24位图!");// 警告             
          ::GlobalUnlock((HGLOBAL) pDoc->GetHObject());// 解除锁定      
           return;                                  //返回
      } 


    LPSTR lpSrcColorBits;//指向调色板的指针
    LPSTR lpSrc;// 指向DIB第i行,第j个象素的指针
    lpSrcColorBits=lpSrcDib+sizeof(BITMAPINFOHEADER);

    unsigned char Intensity;
    unsigned char *lpR,*lpB,*lpG;
    for(int y=0;y<lSrcHeight;y++)
    {
        for(int x=0;x<lSrcWidth;x++)
        {
            lpR = lpSrcStartBits + lSrcLineBytes * (lSrcHeight - 1 - y) + x*3;
            lpB = lpSrcStartBits + lSrcLineBytes * (lSrcHeight - 1 - y) + x*3+1;
            lpG = lpSrcStartBits + lSrcLineBytes * (lSrcHeight - 1 - y) + x*3+2;
            Intensity=0.299 *(* lpR) + 0.587 *(* lpB) + 0.114 * (*lpG );
             if(Intensity>255)
                 Intensity=255;
             if(Intensity<0)
                 Intensity=0;

            *lpR= *lpB= *lpG= Intensity;
        }
    }
    pDoc->SetModifiedFlag(TRUE);
    pDoc->UpdateAllViews(NULL);
    ::GlobalUnlock((HGLOBAL)pDoc->GetHObject());
}

3.实验结果

三、24位彩色转8位灰度
1.原理:申请位图数据所需要的空间,将新图像位数改为8位,建立新的调色板,申请颜色表需要的空间,给颜色表赋值,逐行扫描,对各像素点进行灰度变换,更新图像。
细节:1.申请新图像时,对图像位数进行更改。
2.颜色表的定义 RGBQUAD* pColorTable

2.代码实现

//24位转8位灰度------------------------------------------------------------------------------
void CImgtestView::On248grey()
{
    // TODO: 在此添加命令处理程序代码

    CImgtestDoc* pDoc=GetDocument();


    long lSrcLineBytes;     //图象每行的字节数
    long    lSrcWidth;      //图象的宽度和高度
    long    lSrcHeight;
    int     lpSrcBitCount;       //图像的位深
    LPSTR   lpSrcDib;       //指向源图象的指针  
    LPSTR   lpSrcStartBits; //指向源像素的指针
    lpSrcDib= (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHObject());// 锁定DIB
    if (!lpSrcDib) return;
    if (pDoc->m_dib.GetBitCount(lpSrcDib) != 24)// 判断是否是24-bpp位图
    {       
           AfxMessageBox(L"对不起,不是24位图!");// 警告              
           ::GlobalUnlock((HGLOBAL) pDoc->GetHObject());// 解除锁定     
           return;                                  //返回
     }                              
    lpSrcStartBits=pDoc->m_dib.GetBits(lpSrcDib);           // 找到DIB图象像素起始位置    
    lSrcWidth= pDoc->m_dib.GetWidth(lpSrcDib);                  // 获取图象的宽度      
    lSrcHeight= pDoc->m_dib.GetHeight(lpSrcDib);                    // 获取图象的高度  
    lpSrcBitCount=pDoc->m_dib.GetBitCount(lpSrcDib);                    //获取图像位深
    lSrcLineBytes=pDoc->m_dib.GetReqByteWidth(lSrcWidth * lpSrcBitCount);       // 计算图象每行的字节数
/////////////////////////////////////////////////////////////////////////////////////////////////

    unsigned char*  lpSrc;  


    // 循环变量
    LONG    i;
    LONG    j;  
    // 图像每行的字节数
    LONG    lLineBytes;     
    // 计算图像每行的字节数
    lLineBytes = WIDTHBYTES(lSrcWidth * 24);    
    BITMAPINFOHEADER *pHead;
    RGBQUAD* pColorTable;
    int lineByteNew;
    int biBitCount=8;
    lineByteNew=(lSrcWidth * biBitCount/8+3)/4*4; 
    //申请位图数据所需要的空间,读位图数据进内存
    unsigned char *pBmpBufNew;
    pBmpBufNew=new unsigned char[lineByteNew * lSrcHeight + sizeof(BITMAPINFOHEADER) + 256*4];//申请新图像的空间
    memcpy(pBmpBufNew,(unsigned char *)lpSrcDib,sizeof(BITMAPINFOHEADER));//信息头拷贝
    pHead=(BITMAPINFOHEADER *)pBmpBufNew;
    pHead->biBitCount=8;//改变位数,
    pHead->biHeight=lSrcHeight;
    pHead->biWidth=lSrcWidth;
    pHead->biClrUsed=256;
    pHead->biClrImportant=0;
    pHead->biCompression=0;
    pHead->biPlanes=1;
    pHead->biSize=40;
    pHead->biSizeImage=lineByteNew*lSrcHeight;
    pHead->biXPelsPerMeter=0;
    pHead->biYPelsPerMeter=0;
    pColorTable=(RGBQUAD*)(pBmpBufNew +sizeof(BITMAPINFOHEADER));
    //灰度图像有颜色表,且颜色表表项为
    if(biBitCount==8){
    //申请颜色表所需要的空间,给颜色表赋值
        for(int i=0;i<256;i++)
        {           
            pColorTable[i].rgbBlue=i;
            pColorTable[i].rgbGreen=i;
            pColorTable[i].rgbRed=i;
            pColorTable[i].rgbReserved=0;
        }
    }    

    int Red,Green,Blue,Gray,offset;
    offset=sizeof(BITMAPINFOHEADER)+256*4;
    //逐行扫描
    for(i = 0; i < lSrcHeight; i++)
    {
    //逐列扫描
        for(j = 0; j < lSrcWidth; j++)
        {
        // 指向DIB第i行,第j个象素的指针
            lpSrc = (unsigned char*)lpSrcStartBits+ lLineBytes * (lSrcHeight - 1 - i) + j*3;
            Blue = *lpSrc;
            Green=*(++lpSrc);
            Red=*(++lpSrc);
            Gray= (BYTE)(0.299 * Red + 0.587 * Green + 0.114 * Blue + 0.5);
            // 变换
            lpSrc= (unsigned char*)(pBmpBufNew+offset) + lineByteNew * (lSrcHeight - 1 - i) + j;
            *lpSrc =Gray;                   
        }
    }
            //拷贝
    memcpy(lpSrcDib,pBmpBufNew,lineByteNew * lSrcHeight+ sizeof(BITMAPINFOHEADER) + 256*4);

    delete []pBmpBufNew;



    //设置文档修改标志
    pDoc->SetModifiedFlag(true);
    //更新视图
    pDoc->UpdateAllViews(NULL);
    //解除锁定
    ::GlobalUnlock((HGLOBAL)pDoc->GetHObject ());

}

3.实验结果

四、24位彩色转8位彩色
1.原理:1.建立八叉树,合并子树。将拥有256*256*256色的真彩色图像,转换为256色图像。八叉树节点的特性就是每个节点最多有8个字节点,编号为0~7 。以RGB值建立八叉树,首先建立根节点,然后分别以RGB的每一位分别组成一个0~7的值,依次插入树中。以RGB(123,54,78)为例。

以此类推,将所有的RGB值逐层插入到八叉树中,在每个节点上,记录所有经过的节点的RGB值的总和,以及RGB颜色个数。插入的过程中,如果节点不存在,则需要创建新的节点,然后增加节点计数以及RGB各分量的总和.当在插入时,发现节点已经存在,且是叶子节点,则停止该颜色后续层数节点的插入。插入完一个颜色之后,如果叶子节点数超过了我们要得到的颜色数(256色需要得到256种颜色),这时候就需要合并一些呀字节点了,使的叶子节点的个数不超过我们要得到的颜色数。
由于越底层的节点,数据的敏感度越低,所以,我们将从最底层的节点开始合并。按节点计数值小的优先合并策略,将其字节点的所有RGB分量以及节点计数全部记录到该节点中,并删除其所有子节点。依此进行,直到合并后的叶子数符合要求为止。

2.提取调色板 按照上述的步骤插入完所有的颜色之后,便建立起一颗叶子节点不超过256的八叉树。此时,取出叶子节点中的RGB分量的平均值(分量总和 / 节点计数),即是得到的调色板颜色值。

3.匹配调色板索引 所谓匹配调色板索引,就是根据原始的RGB值,在调色板中查找出最接近的颜色的索引。对每个RGB颜色,分别对调色板数据求各分量的差值的平方和,求的的最小值对应的调色板颜色的索引,即是该RGB颜色匹配到的调色板索引。

细节:1.定义直接插入排序(sort1)和快速排序(sort2)两种排序方式,通过两种排序方式,建立八叉树。计算各个像素值的使用频率,将使用最高的前256种,定义为调色板。其中usedTimes数组中是各颜色使用频率。并用原来的useTimes数组来保存索引值
2.用PFC函数计算,当像素值不在颜色表256位时,寻找这256种中最接近的颜色。

代码实现

//数学函数
int PFC(int color1, int color2)  
{ 
    int x,y,z;  
    x = (color1 & 0xf) - (color2 & 0xf);  
    y = ((color1>>4) & 0xf) - ((color2>>4) & 0xf);  
    z = ((color1>>8) & 0xf) - ((color2>>8) & 0xf);  
    return (x*x + y*y + z*z);  
}

//直接插入排序  
int Sort1(int *src, int *attach, int n)  
{  
    int cur, cur1;  
    int i,j,k=0;  
    for (i = 1; i < n; i++)  
    {  
        cur     = src[i];  
        cur1 = attach[i];  
        for (j = i - 1; j >= 0; j--)  
        {  
            if (cur > src[j])  
            {  
                src[j+1]    = src[j];  
                attach[j+1] = attach[j];  
            }  
            else  
                break;  
        }  
        src[j+1]  = cur;  
        attach[j+1] = cur1;  
    }  
    return 0;  
}  

//快速排序  
int Sort2(int *src, int *attach, int n)  
{  
    if (n <= 12)  
        return Sort1(src, attach, n);  
    int low = 1, high = n - 1;  
    int tmp;  
    while (low <= high)  
    {  
        while (src[low] >= src[0])  
        {  
            if (++low > n - 1)  
                break;  
        }  
        while (src[high] < src[0])  
        {  
            if (--high < 1)  
                break;  
        }  
        if (low > high)  
            break;  
        {  
            tmp                = src[low];  
            src[low]        = src[high];  
            src[high]        = tmp;  
            tmp                = attach[low];  
            attach[low]        = attach[high];  
            attach[high]    = tmp;  
        }  
        low++;  
        high--;  
    }  


    {  
        tmp                = src[low - 1];  
        src[low - 1]    = src[0];  
        src[0]            = tmp;  
        tmp                = attach[low - 1];  
        attach[low - 1]    = attach[0];  
        attach[0]        = tmp;  
    }  
    if (low > 1)  
        Sort2(src, attach, low - 1);  
    if (low < n)  
        Sort2(&src[low], &attach[low], n - low);  
    return 0;  
}  

int Transfer(WORD *color24bit, int len, BYTE *Index, RGBQUAD *mainColor)  
{  
    int usedTimes[4096] = {0};  
    int miniColor[4096];  
    int i;
    for ( i = 0; i < 4096; i++)  
        miniColor[i] = i;  
    i = 0;  
    for (i = 0; i < len; i++)  
    {  
        assert(color24bit[i] < 4096);  
        usedTimes[color24bit[i]]++;  
    }  

    int numberOfColors = 0;  
    for (i = 0; i < 4096; i++)  
    {  
        if (usedTimes[i] > 0)  
            numberOfColors++;  
    }  

    //对usedTimes进行排序,排序过程中minColor数组(保存了颜色值)也作与useTimes  
    //数组相似的交换  
    Sort2(usedTimes, miniColor, 4096);  

    //usedTimes数组中是各颜色使用频率,从高到低排列,显然第numberOfColor个之后的都为0  
    //miniColor数组中是相应的颜色数据  
    //将前256个颜色数据保存到256色位图的调色盘中  
    for (i = 0; i < 256; i++)  
    {  
        mainColor[i].rgbBlue    = (BYTE)((miniColor[i]>>8)<<4);  
        mainColor[i].rgbGreen    = (BYTE)(((miniColor[i]>>4) & 0xf)<<4);  
        mainColor[i].rgbRed        = (BYTE)((miniColor[i] & 0xf)<<4);  
        mainColor[i].rgbReserved = 0;  
    }  

    int *colorIndex = usedTimes;//用原来的useTimes数组来保存索引值  
    memset(colorIndex, 0, sizeof(int) * 4096);  

    if (numberOfColors <= 256)  
    {  
        for (i = 0; i < numberOfColors; i++)  
            colorIndex[miniColor[i]] = i;  
    }  
    else//为第256之后的颜色在前256种颜色中找一个最接近的  
    {  
        for (i = 0; i < 256; i++)  
            colorIndex[miniColor[i]] = i;  

        int index, tmp, tmp1;  
        for (i = 256; i < numberOfColors; i++)  
        {  
            tmp      = PFC(miniColor[0], miniColor[i]);  
            index = 0;  
            for (int j = 1; j < 256; j++)  
            {  
                tmp1 = PFC(miniColor[j], miniColor[i]);  
                if (tmp > tmp1)  
                {  
                    tmp = tmp1;  
                    index = j;  
                }  
            }  
            colorIndex[miniColor[i]] = index;  
        }  
    }  
    //记录各点颜色数据的索引值,即256色位图的颜色数据  
    for (i = 0; i < len; i++)  
    {  
        assert(colorIndex[color24bit[i]] < 256);  
        Index[i] = colorIndex[color24bit[i]];  
    }  

    return 1;        
}  






//24位转8位彩色------------------------------------------------------------------------------
void CImgtestView::On248color()
{
    // TODO: 在此添加命令处理程序代码

    CImgtestDoc* pDoc=GetDocument();// 获取文档 
    ////////////////////////////////////////////////////////////////////////////////////////////////    
    long lSrcLineBytes;     //图象每行的字节数
    long    lSrcWidth;      //图象的宽度和高度
    long    lSrcHeight;
    int     lpSrcBitCount;       //图像的位深
    LPSTR   lpSrcDib;       //指向源图象的指针  
    LPSTR   lpSrcStartBits; //指向源像素的指针
    lpSrcDib= (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHObject());// 锁定DIB
    if (!lpSrcDib) return;
    if (pDoc->m_dib.GetBitCount(lpSrcDib) != 24)// 判断是否是24-bpp位图
    {       
           AfxMessageBox(L"对不起,不是24位图!");// 警告              
           ::GlobalUnlock((HGLOBAL) pDoc->GetHObject());// 解除锁定     
           return;                                  //返回
     }                              
    lpSrcStartBits=pDoc->m_dib.GetBits(lpSrcDib);           // 找到DIB图象像素起始位置    
    lSrcWidth= pDoc->m_dib.GetWidth(lpSrcDib);                  // 获取图象的宽度      
    lSrcHeight= pDoc->m_dib.GetHeight(lpSrcDib);                    // 获取图象的高度  
    lpSrcBitCount=pDoc->m_dib.GetBitCount(lpSrcDib);                    //获取图像位深
    lSrcLineBytes=pDoc->m_dib.GetReqByteWidth(lSrcWidth * lpSrcBitCount);       // 计算图象每行的字节数
/////////////////////////////////////////////////////////////////////////////////////////////////

    unsigned char*  lpSrc;  
    // 循环变量
    LONG    i;
    LONG    j;  
    // 图像每行的字节数
    LONG    lLineBytes;     
    // 计算图像每行的字节数
    lLineBytes = WIDTHBYTES(lSrcWidth * 24);    
    BITMAPINFOHEADER *pHead;
    RGBQUAD* pColorTable=NULL;
    int lineByteNew;
    int biBitCount=8;
    lineByteNew=(lSrcWidth * biBitCount/8+3)/4*4; 
    //灰度图像有颜色表,且颜色表表项为
    if(biBitCount==8){
        //申请颜色表所需要的空间,给颜色表赋值
        pColorTable=new RGBQUAD[256];
        memset(pColorTable, 0, sizeof(RGBQUAD)*256);  
    }     
    BYTE* Index = new BYTE[lineByteNew*lSrcHeight]; //图像数据区的数据(保存在Index中)
    WORD* shortColor = new WORD[lineByteNew*lSrcHeight]; //颜色的高4位
    int iRed, iGreen, iBlue;  
    for (int i = 0; i < lSrcHeight; i++)  
    {//取RGB颜色的高4位  
        for(int j=0;j<lSrcWidth;j++)
        {
            lpSrc = (unsigned char*)lpSrcStartBits+ lLineBytes * (lSrcHeight - 1 - i) + j*3;
            iBlue = (*lpSrc)>>4;
            iGreen=(*(++lpSrc))>>4;
            iRed=(*(++lpSrc))>>4;                       
            shortColor[lineByteNew * (lSrcHeight - 1 - i) + j] =(iBlue<<8) + (iGreen<<4) + iRed ;                   
        }
    } 


    //调用转换函数  24color To->8color
     Transfer(shortColor, lineByteNew*lSrcHeight, Index, pColorTable);  
    /* Transfer(shortColor, nData/3, Index, mainColor);  */




//申请位图数据所需要的空间,读位图数据进内存
    unsigned char *pBmpBufNew;
    pBmpBufNew=new unsigned char[sizeof(BITMAPINFOHEADER) + 256*4];//申请新图像的空间
    memcpy(pBmpBufNew,(unsigned char *)lpSrcDib,sizeof(BITMAPINFOHEADER));//信息头拷贝
    pHead=(BITMAPINFOHEADER *)pBmpBufNew;
    pHead->biBitCount=8;//改变位数,
    pHead->biHeight=lSrcHeight;
    pHead->biWidth=lSrcWidth;
    pHead->biClrUsed=256;
    pHead->biClrImportant=0;
    pHead->biCompression=0;
    pHead->biPlanes=1;
    pHead->biSize=40;
    pHead->biSizeImage=lineByteNew*lSrcHeight;
    pHead->biXPelsPerMeter=0;
    pHead->biYPelsPerMeter=0;

    //拷贝
    memcpy(lpSrcDib,pBmpBufNew, sizeof(BITMAPINFOHEADER));
    memcpy(lpSrcDib+sizeof(BITMAPINFOHEADER),pColorTable, sizeof(RGBQUAD)*256);
    memcpy(lpSrcDib+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256,Index,lineByteNew*lSrcHeight);

    delete []Index;
    delete []shortColor;




    //设置文档修改标志
    pDoc->SetModifiedFlag(true);
    //更新视图
    pDoc->UpdateAllViews(NULL);
    //解除锁定
    ::GlobalUnlock((HGLOBAL)pDoc->GetHObject ());

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值