如何将一个任意色深的CBitmap A转化成32位的CBitmap B?

BloodFighter 2006-10-31 05:51:30
如何,我的思路是通过创建2个32位CDC,分别载入A B,然后BitBlt。
代码如下

BITMAP bm;
pBmpSrc->GetBitmap(&bm);

CDC dcMem;
dcMem.CreateCompatibleDC(NULL);
CBitmap bm32;
bm32.CreateBitmap(bm.bmWidth, bm.bmHeight, 1, 32, NULL);
dcMem.SelectObject(&bm32);
CDC dcSrc;
dcSrc.CreateCompatibleDC(&dcMem);
dcSrc.SelectObject(pBmp);
dcMem.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcSrc, 0, 0, SRCCOPY);

// bm32就是我希望的32位位图

可是实际运行后,这么做是错误的,麻烦有时间的朋友帮忙看看,错在了哪里?
...全文
246 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
booklove 2006-12-18
  • 打赏
  • 举报
回复
GetDIBits
LiChenYue 2006-12-17
  • 打赏
  • 举报
回复
看上去好象都对!
BloodFighter 2006-11-01
  • 打赏
  • 举报
回复
楼上的朋友给的函数缺少些东西,我这么稍作修改,可是运行之后,就没有了效果


void RGBToRGB(
BYTE * pDest, BYTE * pSrc,
tPixelFormat formatDest, tPixelFormat formatSrc,
DWORD dwDestPitch, DWORD dwSrcPitch, UINT nWidth, int nHeight)
{
int iAbsHeight = abs(nHeight);

BITMAPINFOHEADER DestFormat = {sizeof(BITMAPINFOHEADER), nWidth, 1, 1, s_nPixelBytes[formatDest]*8, BI_RGB, 0, 0, 0, 0, 0};
DestFormat.biSizeImage = (s_nPixelBytes[formatDest] * nWidth +3) /4 *4;

BITMAPINFOHEADER SrcFormat = {sizeof(BITMAPINFOHEADER), nWidth, iAbsHeight, 1, s_nPixelBytes[formatSrc]*8, BI_RGB, 0, 0, 0, 0, 0};
SrcFormat.biSizeImage = (s_nPixelBytes[formatSrc] * nWidth +3) /4 *4 * iAbsHeight;

HDC hDC = ::GetDC(0);
BYTE * pBits;
HBITMAP hBmp = CreateDIBSection(hDC, (BITMAPINFO*)&SrcFormat, DIB_RGB_COLORS, (void**)&pBits, 0, 0);
SameFormatConvert(pBits, pSrc, formatSrc,
SrcFormat.biSizeImage / iAbsHeight, dwSrcPitch, nWidth, nHeight);

BITMAP bm;
GetObject(hBmp, sizeof(bm), &bm);
SaveBitmap("pSrc.bmp", bm, pSrc);
SaveBitmap("pBits.bmp", bm, pBits);

for (int i = 0; i < iAbsHeight; i ++)
{
GetDIBits(hDC, hBmp, i, 1, pDest, (BITMAPINFO*)&DestFormat, DIB_RGB_COLORS);
pDest += dwDestPitch;
}

SaveBitmap("pDest.bmp", bm, pDest);


::ReleaseDC(0, hDC);
::DeleteObject(hBmp);
if(NULL!=pBits)delete pBits;
}


测试代码如下
CBitmap bmSrc;
bmSrc.LoadBitmap(IDB_LOGIN);

BITMAP bm;
bmSrc.GetBitmap(&bm);

DWORD iSize = bm.bmWidthBytes * bm.bmHeight;
BYTE *pBufSrc = new BYTE[iSize];
bmSrc.GetBitmapBits(iSize, pBufSrc);

BYTE *pBufDes = new BYTE[iSize/2];

RGBToRGB(pBufDes, pBufSrc, RGB16, RGB32, 1, 1, bm.bmWidth, bm.bmHeight);
DentistryDoctor 2006-10-31
  • 打赏
  • 举报
回复
typedef enum {
UNKNOWN = 0,
YUY2 = 1,
RGB15 = 2, RGB555 = RGB15,
RGB16 = 3, RGB565 = RGB16,
RGB24 = 4, RGB888 = RGB24,
RGB32 = 5, RGB8888 = RGB32,
} tPixelFormat;
static const int s_nPixelBytes[]={0, 2, 2, 2, 3, 4};;

void ColorSpaceConvertor::RGBToRGB(
BYTE * pDest, BYTE * pSrc,
tPixelFormat formatDest, tPixelFormat formatSrc,
DWORD dwDestPitch, DWORD dwSrcPitch, UINT nWidth, int nHeight)
{
int iAbsHeight = abs(nHeight);
BITMAPINFOHEADER * pDestFormat = GetBitmapInfo(formatDest);
LDataBuf bufDestFmt(pDestFormat, GetFormatSize(pDestFormat));
pDestFormat = (BITMAPINFOHEADER *) bufDestFmt.GetData();
pDestFormat->biWidth = nWidth;
pDestFormat->biHeight = 1;
pDestFormat->biSizeImage = (s_nPixelBytes[formatDest] * nWidth +3) /4 *4;

BITMAPINFOHEADER * pSrcFormat = GetBitmapInfo(formatSrc);
LDataBuf bufSrcFmt(pSrcFormat, GetFormatSize(pSrcFormat));
pSrcFormat = (BITMAPINFOHEADER *) bufSrcFmt.GetData();
pSrcFormat->biWidth = nWidth;
pSrcFormat->biHeight = iAbsHeight;
pSrcFormat->biSizeImage = (s_nPixelBytes[formatSrc] * nWidth +3) /4 *4 * iAbsHeight;

HDC hDC = ::GetDC(0);
BYTE * pBits;
HBITMAP hBmp = CreateDIBSection(hDC, (BITMAPINFO*) pSrcFormat, DIB_RGB_COLORS, (void**)&pBits, 0, 0);
SameFormatConvert(pBits, pSrc, formatSrc,
pSrcFormat->biSizeImage / iAbsHeight, dwSrcPitch, nWidth, nHeight);
for (int i = 0; i < iAbsHeight; i ++)
{
GetDIBits(hDC, hBmp, i, 1, pDest, (BITMAPINFO*) pDestFormat, DIB_RGB_COLORS);
pDest += dwDestPitch;
}
::ReleaseDC(0, hDC);
::DeleteObject(hBmp);
if(NULL!=pBits)delete pBits;
}

void ColorSpaceConvertor::SameFormatConvert(
BYTE * pDest, BYTE * pSrc, tPixelFormat format,
DWORD dwDestPitch, DWORD dwSrcPitch, UINT nWidth, int nHeight)
{
UINT nLength = nWidth * s_nPixelBytes[format];
if (nHeight > 0)
{
for (int i = 0; i < nHeight; i ++)
{
CopyMemory(pDest, pSrc, nLength);
pDest += dwDestPitch;
pSrc += dwSrcPitch;
}
}
else
{
pDest += dwDestPitch * (- nHeight - 1);
for (int i = 0; i > nHeight; i --)
{
CopyMemory(pDest, pSrc, nLength);
pDest -= dwDestPitch;
pSrc += dwSrcPitch;
}
}
}
BloodFighter 2006-10-31
  • 打赏
  • 举报
回复
我逐步跟踪了一下,
应该是dcSrc这个表面没有创建出来,可是就算是我dcSrc.CreateCompatibleDC(NULL);这样写,这个表面还是不会被创建,然后,自然dcSrc.SelectObject() 以及dcMem.BitBlt(—dcSrc) 也是无效的,又没有朋友帮忙解释一下,为什么这么写就是错误的,应该如果做?

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧