之前通过bmp文件路径获取的位图数据的数组,现在需要改成通过资源读取。我将24bit的bmp图做成了资源,但获取的位图数据的数组,与之前不一致。导致图像显示错误,请问如何修改。文件路径的方式:
    // Read File
    bOpen = clsFile.Open( csBmpPathName, 
        CFile::modeRead | CFile::shareDenyWrite, e );    // Read bitmap header
    BITMAPFILEHEADER stBmpFileHeader;
    UINT nFileReadBytes = UINT_ZERO;
    nFileReadBytes = clsFile.Read( &stBmpFileHeader, 
        sizeof( BITMAPFILEHEADER ));    // Read bitmap info
    BITMAPINFOHEADER m_stBmpInfoHeader;
    nFileReadBytes = clsFile.Read( 
        &m_stBmpInfoHeader, sizeof( BITMAPINFOHEADER ));
    if( nFileReadBytes != sizeof( BITMAPINFOHEADER ))
    {
        return E_FAIL;
    }    // Read bitmap data
    BYTE* pbyTempImageData =
        new BYTE[lDataSize];
    nFileReadBytes = clsFile.Read( pbyTempImageData,
        lDataSize );
读取资源的方式: m_hbitmap_avc = LoadBitmap(_Module.GetModuleInstance(), MAKEINTRESOURCE(IDB_BITMAP_AVC)); CBitmap bitmap_avc;
BITMAP bm_avc;
BYTE *pData, *pDataReverse; bitmap_avc.Attach(m_hbitmap_avc);
bitmap_avc.GetBitmap(&bm_avc); LONG width = bm_avc.bmWidth;
LONG height = bm_avc.bmHeight;
LONG dwSize = bm_avc.bmHeight * bm_avc.bmWidthBytes; pData = new BYTE[dwSize];
pDataReverse = new BYTE[dwSize];        //Get bmp data
LONG dlcount2 = GetBitmapBits(m_hbitmap_avc, bm_avc.bmWidthBytes, pData); //reverse bmp data
for(int i = 0; i < dwSize; i++)
{
pDataReverse[i] = pData[dwSize - 1 - i];
}

解决方案 »

  1.   

    此外获取bmp数据,必须是与设备无关的,多谢!
      

  2.   

    //reverse bmp data
    for(int i = 0; i < dwSize; i++)
    {
    pDataReverse[i] = pData[dwSize - 1 - i];
    } 这是在干嘛?
      

  3.   

    BMP文件存储数据是倒叙的,也就是从图像的右下角开始存储,文件的最后是图像的左上角(这个来历可以看:WINDOWS编程中介绍);
    使用GetBitmapBits取得的BUFFER,位图的右下角的内容为第一个字节,实际上和真正的图像字节应该是一样的,
    所以我做了逆排序。
      

  4.   

    你弄错了,设备无关位图数据原点不是在右下角,而是在左下角。要想正过来,需要按行逆转,而不是按像素逆转。你这样做,不但把数据中用来在行尾填充对齐的无用数据移到了行首,而且把RGB的顺序都搞乱了。
      

  5.   

    印象中bitmap资源只支持256色以下的图片,24位颜色的需要特别的处理和操作吧,你看看是不是颜色格式多导致的问题。
      

  6.   

    你说需要逆转数据,我还以为你用的是GetDIBits,原来是用的GetBitmapBits。如果用GetDIBits,就不会出现格式不符的问题,这个函数会自动处理转换像素格式,不过经过了256色格式之后,颜色丢失是必然的。
      

  7.   

    好久没用WindowsAPI处理图像了,手头目前没有现成的代码。
    主要思路就是:
    CreateCompatibleDC创建一个与设备相关DC
    SelectedObject把位图选进DC
    为GetDIBits准备数据空间,计算lpBits内存块的大小时要注意,每行的长度都需要是4的整数倍。你如果不知道位图的大小,可以先把lpBits参数设为NULL,并且用0填充LPBITMAPINFO lpbi结构,把他们传进去后,GetDIBits会将lpbi所有的信息都填好,这时你就可以获得位图的信息了。为lpBits分配好空间后,重新设置lpbi结构,关键是这三条:
    bi.bmiHeader.biPlanes = 1; 
    bi.bmiHeader.biBitCount =24; 
    bi.bmiHeader.biCompression = BI_RGB; 
    调用时usage参数为DIB_RGB_COLORS,成功后就会得到一个24位的位图数据,这个数据可以用SetDIBits直接显示,也可以访问lpBits中的内容进行处理。
      

  8.   

    楼猪,给你一个GDI+读取的列子吧完全正确的代码
    // 使用8位资源位图填充全局的灰度图像缓冲区域
    // 将图像资源nID的数据读取到数组pBuffer
    BOOL CImgProcessDlg::FillImageBuf( BYTE *pBuffer, UINT nID)
    {
    ASSERT(pBuffer);
    if (!pBuffer)
    return FALSE; //IDB_BITMAP_KS是Bitmap资源,一张1024*576*8的图片
    Gdiplus::Bitmap *pBitmap = Bitmap::FromResource(AfxFindResourceHandle(MAKEINTRESOURCE(nID), RT_BITMAP),MAKEINTRESOURCE(nID)); int  nWidth = pBitmap->GetWidth(); //1024 pixel
    int  nHeight = pBitmap->GetHeight(); //576  pixel
    Rect rect( 0, 0, nWidth, nHeight );  BitmapData    *pBitmapData = new BitmapData;
    pBitmap->LockBits( &rect, ImageLockModeRead, pBitmap->GetPixelFormat(), pBitmapData );
    BYTE *pByte = (BYTE *) pBitmapData->Scan0;
    int nOffset = pBitmapData->Stride - nWidth; // 8位灰度图像 for( int row = 0; row < nHeight; row++ )
    {
    for( int col = 0; col < nWidth; col++ )
    {
    *pBuffer = pByte[0];
    pBuffer++; pByte += 1;
    }
    pByte += nOffset;
    }
    pBitmap->UnlockBits( pBitmapData ); //clean:
    delete pBitmapData; // 必须释放
    delete pBitmap;    return TRUE;
    }
      

  9.   

    需要提醒你的是,通常的图像数据的扫描行存储是从上往下的,也就是说像素的原点在top-left位置,但是GDI+读取的图像的像素的原点位置在bottom-left,就是说它的扫描行从下往上存放的。