为什么BMP文件保存后,图像发生平移?

请教一下各位大神,SaveFile函数代码如下,为什么保存后的图像总会发生水平偏移(而且是循环反向序列)呢?(因为CSDN不能上传.bmp图片,故转换成.jpg图片)
图片说明
图片说明
求给个解决办法,谢谢!
代码块中涉及的变量有:

        pDIB=(BYTE*)::GlobalLock(m_hDIB);//位图指针
        pBFH=(BITMAPFILEHEADER*)pDIB;
        pBIH=(BITMAPINFOHEADER*)&pDIB[sizeof(BITMAPFILEHEADER)];
        pQuad=(RGBQUAD*)&pDIB[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
        pBits=(BYTE*)&pDIB[pBFH->bfOffBits];
        nWidth = pBIH->biWidth;
        nHeight = pBIH->biHeight;
        nBitCount = pBIH->biBitCount;
        numquad=1<<nBitCount;//计算调色板数目
 void ImageProc::SaveFile(void)
{
    DWORD DIBSize;
    LPCTSTR lpszFilter=_T("BMP Files(*.bmp)|*.bmp|任何文件|*.*||");
    CFileDialog dlg(FALSE,lpszFilter,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,lpszFilter,NULL);

    if (dlg.DoModal()!=IDOK)
    {   
        return;
    }
    CFile file;
    CFileException fe;
    if (!file.Open(dlg.GetPathName(), CFile::modeCreate | CFile::modeReadWrite | CFile::shareExclusive, &fe))
    {
        //ReportSaveLoadException(dlg.GetPathName(), &fe, TRUE, AFX_IDP_INVALID_FILENAME);//失败
        return;
    }
    DIBSize=WIDTHBYTES(nWidth*nBitCount)*nHeight;//位图实际所占字节数计算公式

    file.SeekToBegin();
    file.Write(pBFH,sizeof(BITMAPFILEHEADER));  //文件头结构写进文件
    file.Write(pBIH,sizeof(BITMAPINFOHEADER)); //文件信息头写入文件 
    file.Write(pQuad,sizeof(RGBQUAD)*numquad);//如果有颜色表,颜色表写进文件
    file.Write(pDIB,DIBSize);                //位图实际所占字节数写进文件
    file.Close();
}

用winhex/ultraedit看下,保存的文件的文件头是否有问题。

numquad=1<<nBitCount;//计算调色板数目

还用到了调色板,这样发生的偏移,先试试24位图和32的位图看看,没有调色板的,如果按照你的保存代码,如果还出问题就是保存出错,如果没有问题,就可能是调色板这里出错了。

应该不是你的保存函数有问题,而是你调用位图指针和调色板的地方,bmp调色板的索引出现问题了,比如第一行像素中,你把第二个像素点的索引给
了第一个点,这样就出现平移情况

Winhex Ultraedit 检查下 看看头部或尾部

你的图片数据是存在问题的,我觉得你应该加载一个图片然后保存这样对比一下

图片发生了移位,感觉像是调色板索引的问题