怎么用GetDIBits获取某点的颜色值

bobo3198 2010-01-29 07:30:40
RT.

bitmap已经加载IDB_BITMAP1;大小1024*768

有pDCDest, pDCSrc,现想用GetDIBIts获取某点pt(300, 150)的颜色值

...全文
813 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
郑不器 2011-12-22
  • 打赏
  • 举报
回复
学习了。。。。。。。。
cctvlaaax 2011-09-13
  • 打赏
  • 举报
回复
Cimage 类有个成员 GetPIXEL getBIT 可以
bobo3198 2010-02-02
  • 打赏
  • 举报
回复
还是不行。

if ( bitmap.GetSafeHandle() == NULL || pDC->GetSafeHdc() == NULL )
return FALSE;

CPoint pt(650, 120);

HBITMAP hbmp = (HBITMAP)bitmap.GetSafeHandle();

BITMAP bm;
bitmap.GetBitmap(&bm);

BITMAPINFO bmpInfo;
/*bmpInfo.bmiHeader.biSize = sizeof(bmpInfo.bmiHeader);
bmpInfo.bmiHeader.biWidth = bm.bmWidth;
bmpInfo.bmiHeader.biHeight = bm.bmHeight;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = bm.bmBitsPixel;
bmpInfo.bmiHeader.biCompression = BI_RGB;
bmpInfo.bmiHeader.biSizeImage = bm.bmWidth * bm.bmHeight;
bmpInfo.bmiHeader.biXPelsPerMeter = 0;
bmpInfo.bmiHeader.biYPelsPerMeter = 0;
bmpInfo.bmiHeader.biClrUsed = 1;
bmpInfo.bmiHeader.biClrImportant = 1;*/ 无论是否注释,结果均不对

int nbyte = bm.bmBitsPixel / 8;

BYTE *bits = new BYTE[bm.bmHeight * bm.bmWidthBytes];

GetDIBits(pDC->GetSafeHdc(), hbmp, 0, bm.bmHeight, bits, &bmpInfo, DIB_RGB_COLORS);

int i = (pt.y * bm.bmWidth + pt.x ) * nbyte;

BYTE r = bits[i+2];
BYTE g = bits[i+1];
BYTE b = bits[i+0];

clr/*COLORREF*/ = pDC->GetPixel(pt);

int r1 = GetRValue(clr);
int g1 = GetGValue(clr);
int b1 = GetBValue(clr);

CString aa;
aa.Format("%d, %d, %d, clr=%d, %d, %d", r, g, b, r1, g1, b1);
MessageBox(aa);输出为205,205,205, clr=247,202,82
bobo3198 2010-02-02
  • 打赏
  • 举报
回复
再分享下给不知道的朋友。

BYTE *bits = (BYTE*)new BYTE[bm.bmWidth * bm.bmHeight * nbyte];
bitmap.GetBitmapBits(bm.bmWidth * bm.bmHeight * bm.bmWidthBytes, bits);这两行也能取到。之后以下标pt.x * nbyte + pt.y * bm.bmWidth来访问bits就行了,不需要再和BITMAPINFO纠缠。

但是不知道对于32、24位图,CBitmap::GetBitmapBits与GetDIBits哪个执行效率好些。
bobo3198 2010-02-02
  • 打赏
  • 举报
回复
谢谢,看了这篇文章后解决了,我的原码都没变,变成了个bmpInfo.bmiHeader.biHeight = bm.bmHeight变成-bm.bmHeight就解决问题了,虽然MSDN上说明了在DIB在内存里是从下往上存取的,但一直不明白。直到看到这样赋值后才有点明了。
sjdev 2010-02-02
  • 打赏
  • 举报
回复
你可以看看文章中是如何GetDIBits之后得到rgb值的。
http://blog.csdn.net/sjdev/archive/2010/01/23/5249373.aspx
sjdev 2010-02-02
  • 打赏
  • 举报
回复
这篇文章中可能会帮你的忙。
wltg2001 2010-02-02
  • 打赏
  • 举报
回复
要不不用GetDIBits了,改用CBitmap类的GetBitmapBits试试
wltg2001 2010-02-01
  • 打赏
  • 举报
回复
BYTE *bits = new BYTE[bm.bmWidth * bm.bmHeight * nbyte];
=============
这个应该不行,对于BMP来说,有一个行对齐问题,所以应该写作:
BYTE *bits=new BYTE[bm.bmHeight*bm.bmWidthBytes];才行。
bobo3198 2010-02-01
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 wltg2001 的回复:]
引用 5 楼 bobo3198 的回复:
能不能给段代码吧,我先前是这样做的,但是不成功。

GetDIBits(pDCDest->m_hDC, hBitmap, 0, nHeight, NULL, &bmpInfo, DIB_RGB_COLORS);

BYTE *bufBmp。。。。。。。我不会对这个进行赋值

你这个首先要确定是不是32位的位图,一般用GetBitmap先获取位图的相关信息,
GetBitmap(&Bmp);
int PixelBytes=Bmp.bmBitsPixel/8;
int i=y*Bmp.bmWidthBytes+x*PixelBytes;//这里的x,y就点的坐标,i表示在数组中首地址
bufBmp[i+0]表示Blue bufBmp[i+1]表示G bufBmp[i+2]表示R
[/Quote]

还是不对,可能是我前面的代码有问题。
if ( bitmap.GetSafeHandle() == NULL || pDC->GetSafeHdc() == NULL )
return FALSE;

HBITMAP hbmp = (HBITMAP)bitmap.GetSafeHandle();

BITMAP bm;
bitmap.GetBitmap(&bm);

BITMAPINFO bmpInfo;
bmpInfo.bmiHeader.biSize = sizeof(bmpInfo.bmiHeader);

int nbyte = bm.bmBitsPixel / 8;

BYTE *bits = new BYTE[bm.bmWidth * bm.bmHeight * nbyte];

GetDIBits(pDC->GetSafeHdc(), hbmp, 0, bm.bmHeight, bits, &bmpInfo, DIB_RGB_COLORS) ;

int i = 120 * bm.bmWidthBytes + 750 * nbyte;
//int i = (120 * bm.bmWidth + 750) * nbyte;这个也不行

BYTE r = bits[i+2];
BYTE g = bits[i+1];
BYTE b = bits[i];

CString aa;
aa.Format("%d, %d, %d", r, g, b);
MessageBox(aa);
wltg2001 2010-01-29
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 bobo3198 的回复:]
能不能给段代码吧,我先前是这样做的,但是不成功。

GetDIBits(pDCDest->m_hDC, hBitmap, 0, nHeight, NULL, &bmpInfo, DIB_RGB_COLORS);

BYTE *bufBmp。。。。。。。我不会对这个进行赋值
[/Quote]
你这个首先要确定是不是32位的位图,一般用GetBitmap先获取位图的相关信息,
GetBitmap(&Bmp);
int PixelBytes=Bmp.bmBitsPixel/8;
int i=y*Bmp.bmWidthBytes+x*PixelBytes;//这里的x,y就点的坐标,i表示在数组中首地址
bufBmp[i+0]表示Blue bufBmp[i+1]表示G bufBmp[i+2]表示R
ga6840 2010-01-29
  • 打赏
  • 举报
回复
函数返回的就是一个24位的dib date
把Context(lo_x,lo_y);换成你要改的rgb
ga6840 2010-01-29
  • 打赏
  • 举报
回复


char* CBitMap::DIB_Date()
{
int lo_w_byte = m_width*m_BytesPerPixel + (m_width % 4) ;

char* lo_p = new char[lo_w_byte*m_height];
int lo_i=0;

for(int lo_y = 0; lo_y < m_height ; lo_y++)
{
for(int lo_x = 0; lo_x < m_width ; lo_x++)
{
*(RGB*)(&(lo_p[lo_i])) = Context(lo_x,lo_y);
lo_i += m_BytesPerPixel;
}
lo_i += m_width % 4; }

return lo_p;
}




Context(lo_x,lo_y);返回的就是一个RGB
bobo3198 2010-01-29
  • 打赏
  • 举报
回复


我查的资料是这样。

GetDIBits(pDCDest->m_hDC, hBitmap, 0, nHeight, bufBmp, &bmpInfo, DIB_RGB_COLORS);

成功后可以

int r = bufBmp[pt.x * pt.y + 2];
int g = bufBmp[pt.x * pt.y + 1];
int b = bufBmp[pt.x * pt.y + 0];

但是不对
bobo3198 2010-01-29
  • 打赏
  • 举报
回复

能不能给段代码吧,我先前是这样做的,但是不成功。

GetDIBits(pDCDest->m_hDC, hBitmap, 0, nHeight, NULL, &bmpInfo, DIB_RGB_COLORS);

BYTE *bufBmp。。。。。。。我不会对这个进行赋值
nintendo_dskay 2010-01-29
  • 打赏
  • 举报
回复
记得bmp数据存放的顺序是BLUE、Green、Red、Alpha、不要弄反了
nintendo_dskay 2010-01-29
  • 打赏
  • 举报
回复
GetDIBits获取的是bmp中的RGB数据,对于32位的BMP图像来说它的存放格式是BGRA,分别是Blue、Green、Red、Alpha,其中Alpha是透明度,一个占4个字节。并且获取出来的数据是从左到右一行行来取出的,所以比如你要获取(x, y)位置的像素值(其中x、y的最小值为0),只要用GetDIBits将bmp的数据获取到缓冲区后,用一个BYTE指针指到缓冲区索引为
(y * width + x)* 4 位置的字节即可
bobo3198 2010-01-29
  • 打赏
  • 举报
回复

可是可以,但是我想用GetDIBits操作内存
nintendo_dskay 2010-01-29
  • 打赏
  • 举报
回复
直接调用CDC的GetPixel不可以吗?

15,977

社区成员

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

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