怎样把位图画到内存里面? 怎么用CDC将位图画到内存里面,而且位图是黑白的,怎么样从这片内存里取出位图的一部分或全部? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 创建一个内存兼容dc和内存兼容bitmap,dc.bitblt就可以了要想画一部分,可以使用strechblt CDC MemDC; //首先定义一个显示设备对象 MemDC.CreateCompatibleDC(NULL); 在MeMDC上作图即可。 参考:这是将BMP打印到屏幕的代码:void CCreateRandomBMPDlg::OnBtnTest(){ // TODO: Add your control notification handler code here HBITMAP hBmp; CFileDialog dlg(TRUE, "bmp", NULL, 0, "位图文件 (*.bmp)|*.bmp||", this); if (dlg.DoModal() != IDOK) { return; } hBmp = (HBITMAP) LoadImage(NULL, dlg.GetPathName(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); if (hBmp == NULL) { return; } BITMAP bm; PBITMAPINFO bmpInf; if (GetObject(hBmp, sizeof(bm), &bm) == 0) return ; int nPaletteSize = 0; if (bm.bmBitsPixel < 16) nPaletteSize = (int) pow(2, bm.bmBitsPixel); bmpInf = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * nPaletteSize); //----------------------------------------------- bmpInf->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmpInf->bmiHeader.biWidth = bm.bmWidth; bmpInf->bmiHeader.biHeight = bm.bmHeight; bmpInf->bmiHeader.biPlanes = bm.bmPlanes; bmpInf->bmiHeader.biBitCount = bm.bmBitsPixel; bmpInf->bmiHeader.biCompression = BI_RGB; bmpInf->bmiHeader.biSizeImage = (bm.bmWidth + 7) / 8 * bm.bmHeight * bm.bmBitsPixel; bmpInf->bmiHeader.biXPelsPerMeter = 0; bmpInf->bmiHeader.biYPelsPerMeter = 0; bmpInf->bmiHeader.biClrUsed = 0; bmpInf->bmiHeader.biClrImportant = 0; //----------------------------------------------- HDC hDC = ::GetWindowDC(NULL); if (!::GetDIBits(hDC, hBmp, 0, (WORD) bm.bmHeight, NULL, bmpInf, DIB_RGB_COLORS)) { LocalFree(bmpInf); ::ReleaseDC(NULL, hDC); return ; } void* buf = (void*) new char[bmpInf->bmiHeader.biSizeImage]; if (buf == NULL) { ::ReleaseDC(NULL, hDC); LocalFree(bmpInf); return ; } if (!::GetDIBits(hDC, hBmp, 0, (UINT) bm.bmHeight, buf, bmpInf, DIB_RGB_COLORS)) { ::ReleaseDC(NULL, hDC); delete[]buf; LocalFree(bmpInf); return ; } ::ReleaseDC(NULL, hDC); CString sMsg; sMsg.Format("BitsPixel:%d,width:%d,height:%d", bm.bmBitsPixel, bm.bmWidth, bm.bmHeight); AfxMessageBox(sMsg); CClientDC dc(this); if (bm.bmBitsPixel == 8) { BYTE* pData = (BYTE*) buf; int nWidth = bm.bmWidth; while (nWidth % 4 != 0) { //Bmp每行数据都是4个字节的整数倍。 nWidth++; } for (int i = 0; i < bm.bmHeight; i++) { for (int j = 0; j < bm.bmWidth; j++) { RGBQUAD rgbQ; rgbQ = bmpInf->bmiColors[pData[i * nWidth + j]]; dc.SetPixel(j, bm.bmHeight - i, RGB(rgbQ.rgbRed, rgbQ.rgbGreen, rgbQ.rgbBlue)); } } } else if (bm.bmBitsPixel == 16) { BYTE* pData = (BYTE*) buf; int nWidth = bm.bmWidth*2; while (nWidth % 4 != 0) { nWidth++; } BYTE red, green, blue; for (int i = 0; i < bm.bmHeight; i++) { for (int j = 0; j < bm.bmWidth; j++) { blue = pData[i * nWidth + j * 2] & 0x1F; green = pData[i * nWidth + j * 2] >> 5; green |= (pData[i * nWidth + j * 2 + 1] & 0x03) << 3; red = (pData[i * nWidth + j * 2 + 1] >> 2) & 0x1F; WORD wRed = red*8; WORD wBlue = blue*8; WORD wGreen = green*8; red = min(255, wRed); blue = min(255, wBlue); green = min(255, wGreen); dc.SetPixel(j, bm.bmHeight - i, RGB(red, green, blue)); } } } else if (bm.bmBitsPixel == 24) { BYTE* pData = (BYTE*) buf; int nWidth = bm.bmWidth*3; while (nWidth % 4 != 0) { nWidth++; } for (int i = 0; i < bm.bmHeight; i++) { for (int j = 0; j < bm.bmWidth; j++) { dc.SetPixel(j, bm.bmHeight - i, RGB(pData[i * nWidth + j * 3 + 2], pData[i * nWidth + j * 3 + 1], pData[i * nWidth + j * 3])); } } } else if (bm.bmBitsPixel == 32) { BYTE* pData = (BYTE*) buf; int nWidth = bm.bmWidth*4; for (int i = 0; i < bm.bmHeight; i++) { for (int j = 0; j < bm.bmWidth; j++) { dc.SetPixel(j, bm.bmHeight - i, RGB(pData[i * nWidth + j * 4 + 2], pData[i * nWidth + j * 4 + 1], pData[i * nWidth + j * 4])); } } } delete[]buf; DeleteObject(hBmp); LocalFree(bmpInf);} 我还想问一下:CDC dc;CDC dcMem;CBitmap Bitmap;dcMem.CreateCompatibleDC(&dc); //???这个函数的从参数怎么填,&dc还是NULLBitmap.CreateCompatibleBitmap(&dc, 320, 240); //第参数怎么填,&dc还是&dcMem然后用dcMem画图就可以了,但是图画到了dcMem里还是Bitmap里?另外strechblt好像是进行压缩和拉伸,而我现在要去的是位图里面的一部分,例如在rect(10,10,20,20)里的一部分 还请大侠多执教,最好给我写一些程序,谢谢了! 怎么查看一台电脑是否在NAT后? 有关动态加载组件问题 WaitForSingleObject 等待一个事件,多次执行…… 怎么样保存多个HTML为一个自定义格式的文件呢 用TAPI通过MODEM对拨,拨通后串口传送数据的问题 如何让MFC派生类正常工作?高手指教 Clistctrl排序?散分 关于删除一个文件 ★报酬500元,为原来的exe加个外壳,需求如下 购买程序,急急急 像VC那样左边的浮动窗口与主框架如何通信? 急,怎么配置VC++6.0的开发环境才能生成INI文件呢,在线守候""
要想画一部分,可以使用strechblt
MemDC.CreateCompatibleDC(NULL);
在MeMDC上作图即可。
void CCreateRandomBMPDlg::OnBtnTest()
{
// TODO: Add your control notification handler code here
HBITMAP hBmp; CFileDialog dlg(TRUE, "bmp", NULL, 0, "位图文件 (*.bmp)|*.bmp||", this); if (dlg.DoModal() != IDOK)
{
return;
} hBmp = (HBITMAP) LoadImage(NULL, dlg.GetPathName(), IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE | LR_CREATEDIBSECTION); if (hBmp == NULL)
{
return;
} BITMAP bm;
PBITMAPINFO bmpInf; if (GetObject(hBmp, sizeof(bm), &bm) == 0)
return ; int nPaletteSize = 0; if (bm.bmBitsPixel < 16)
nPaletteSize = (int) pow(2, bm.bmBitsPixel); bmpInf = (PBITMAPINFO) LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * nPaletteSize); //-----------------------------------------------
bmpInf->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInf->bmiHeader.biWidth = bm.bmWidth;
bmpInf->bmiHeader.biHeight = bm.bmHeight;
bmpInf->bmiHeader.biPlanes = bm.bmPlanes;
bmpInf->bmiHeader.biBitCount = bm.bmBitsPixel;
bmpInf->bmiHeader.biCompression = BI_RGB;
bmpInf->bmiHeader.biSizeImage = (bm.bmWidth + 7) /
8 * bm.bmHeight * bm.bmBitsPixel;
bmpInf->bmiHeader.biXPelsPerMeter = 0;
bmpInf->bmiHeader.biYPelsPerMeter = 0;
bmpInf->bmiHeader.biClrUsed = 0;
bmpInf->bmiHeader.biClrImportant = 0;
//----------------------------------------------- HDC hDC = ::GetWindowDC(NULL);
if (!::GetDIBits(hDC, hBmp, 0, (WORD) bm.bmHeight, NULL, bmpInf,
DIB_RGB_COLORS))
{
LocalFree(bmpInf);
::ReleaseDC(NULL, hDC);
return ;
} void* buf = (void*) new char[bmpInf->bmiHeader.biSizeImage];
if (buf == NULL)
{
::ReleaseDC(NULL, hDC);
LocalFree(bmpInf);
return ;
} if (!::GetDIBits(hDC, hBmp, 0, (UINT) bm.bmHeight, buf, bmpInf,
DIB_RGB_COLORS))
{
::ReleaseDC(NULL, hDC);
delete[]buf;
LocalFree(bmpInf);
return ;
} ::ReleaseDC(NULL, hDC); CString sMsg;
sMsg.Format("BitsPixel:%d,width:%d,height:%d", bm.bmBitsPixel, bm.bmWidth,
bm.bmHeight); AfxMessageBox(sMsg); CClientDC dc(this); if (bm.bmBitsPixel == 8)
{
BYTE* pData = (BYTE*) buf; int nWidth = bm.bmWidth;
while (nWidth % 4 != 0)
{
//Bmp每行数据都是4个字节的整数倍。
nWidth++;
} for (int i = 0; i < bm.bmHeight; i++)
{
for (int j = 0; j < bm.bmWidth; j++)
{
RGBQUAD rgbQ;
rgbQ = bmpInf->bmiColors[pData[i * nWidth + j]];
dc.SetPixel(j, bm.bmHeight - i,
RGB(rgbQ.rgbRed, rgbQ.rgbGreen, rgbQ.rgbBlue));
}
}
}
else if (bm.bmBitsPixel == 16)
{
BYTE* pData = (BYTE*) buf; int nWidth = bm.bmWidth*2;
while (nWidth % 4 != 0)
{
nWidth++;
} BYTE red, green, blue; for (int i = 0; i < bm.bmHeight; i++)
{
for (int j = 0; j < bm.bmWidth; j++)
{
blue = pData[i * nWidth + j * 2] & 0x1F;
green = pData[i * nWidth + j * 2] >> 5;
green |= (pData[i * nWidth + j * 2 + 1] & 0x03) << 3;
red = (pData[i * nWidth + j * 2 + 1] >> 2) & 0x1F; WORD wRed = red*8;
WORD wBlue = blue*8;
WORD wGreen = green*8; red = min(255, wRed);
blue = min(255, wBlue);
green = min(255, wGreen); dc.SetPixel(j, bm.bmHeight - i, RGB(red, green, blue));
}
}
}
else if (bm.bmBitsPixel == 24)
{
BYTE* pData = (BYTE*) buf; int nWidth = bm.bmWidth*3;
while (nWidth % 4 != 0)
{
nWidth++;
} for (int i = 0; i < bm.bmHeight; i++)
{
for (int j = 0; j < bm.bmWidth; j++)
{
dc.SetPixel(j, bm.bmHeight -
i,
RGB(pData[i * nWidth + j * 3 + 2],
pData[i * nWidth + j * 3 + 1],
pData[i * nWidth + j * 3]));
}
}
}
else if (bm.bmBitsPixel == 32)
{
BYTE* pData = (BYTE*) buf; int nWidth = bm.bmWidth*4; for (int i = 0; i < bm.bmHeight; i++)
{
for (int j = 0; j < bm.bmWidth; j++)
{
dc.SetPixel(j, bm.bmHeight -
i,
RGB(pData[i * nWidth + j * 4 + 2],
pData[i * nWidth + j * 4 + 1],
pData[i * nWidth + j * 4]));
}
}
} delete[]buf; DeleteObject(hBmp);
LocalFree(bmpInf);
}
CDC dcMem;
CBitmap Bitmap;dcMem.CreateCompatibleDC(&dc); //???这个函数的从参数怎么填,&dc还是NULL
Bitmap.CreateCompatibleBitmap(&dc, 320, 240); //第参数怎么填,&dc还是&dcMem然后用dcMem画图就可以了,但是图画到了dcMem里还是Bitmap里?另外strechblt好像是进行压缩和拉伸,而我现在要去的是位图里面的一部分,例如在rect(10,10,20,20)里的一部分
还请大侠多执教,最好给我写一些程序,谢谢了!