8910|17

1

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

Wince下如何使用CreateDIBSection第四个参数返回的指针 [复制链接]

我在Wince下打开了一张图片并且成功截取了图片  保存截图
使用CreateDIBSection大概如下(我那个也差不多是这样子,因为程序我没有拿回来):
hBitmap=CreateDIBSection(hDc,(BITMAPINFO *)lpImgData,DIB_RGB_COLORS,   
  (void **)&ptData,NULL, 0);

现在我想读取出又第四个参数返回的像素点的RGB值,但是网上有人说这个返回值里面的内容是空的,就是里面没有实质的RGB值。那我怎么使用这个参数把这些像素点的信息保存下来呢?

我也看到有些人用memcpy(ptData, lpPtr, ImgSize);之类的我懵懂得知道只是复制的意思,但是怎么用,用来做什么我不清楚。还有就是CopyMemory(……);
GetPiexl(dc,x,y)这个用不起,太多点,仪器反应不过来。
我现在就是想用ptData读出截取区域中像素点的RGB信息,保存起来,然后做个能修改这些RGB值的接口。

各位大虾指点一下小弟,我是菜鸟来的,也是刚接触,说得太深入我不懂,能否给出能满足上面要求的代码,或者教教我怎么使用也好,最好能简要说明一下为什么这样。因为现在手头没有资料,不知从何入手啊。

叩谢!
再次感谢!
此帖出自WindowsCE论坛

最新回复

我现在可以保存截取下的像素值了,不过是用GetPixel一个个保存下来的。虽然很笨,很慢,但先解决这个问题上交吧,期限已经超了。你对CreateDIBSection的解析我暂时还没有看。你说的方法我都保存了,可能是我写的程序不对或者是少了哪方面的知识,一直无法做出来,所以先不用你说的方法。待交了这份活后,再好好恶补这方面的知识,理解理解你说的方法,自己做份好的出来。 感谢各位的帮忙! 特别感谢nommm虚心教导!   详情 回复 发表于 2010-6-9 13:16
点赞 关注
 

回复
举报

3

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
菜鸟没有关系,关键是要想学,而不是企望别人给代码

网上关系 CreateDIBSection() 函数使用的很多,好像我有eeworld的空间中也有一片这样的文章,努力学习吧,不可能,也不想一辈子都当菜鸟吧.
此帖出自WindowsCE论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
CreateDIBSection 是创建一个无关位图,ptData指向的区域,当然是空白的,需要你自己往里面填。
此帖出自WindowsCE论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

4
 
    HANDLE hFile = CreateFile(pszFile,GENERIC_WRITE,(DWORD) 0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
    if (hFile == INVALID_HANDLE_VALUE)
        {
        return ;
        }
    WriteFile(hFile, &bmBITMAPFILEHEADER, sizeof(BITMAPFILEHEADER), &dwNumBytes, NULL);
    WriteFile(hFile, &(rgb24bits.bmiHeader), sizeof(BITMAPINFOHEADER), &dwNumBytes, NULL);
    WriteFile(hFile,lpBits,3*nWidth*nHeight,&dwNumBytes, NULL);
我的代码片段是这样的。最后一个WriteFile是不是就是AAa-tnT你说的往空白区域填充呢?或者是其他意思。因为时间比较紧迫,我自己更急,所以不能慢慢的学习。现在我是这个不懂那个也不清楚,我是新人所以我的电脑不能上网,只能在公司里的公共电脑上。查找资料不是很方便。
91program你空间里的文章我看了。请原谅我的无知,我只能从里面提取到那是显示图片保存图片的知识哦,没能找到该怎么获得位图RGB值的
此帖出自WindowsCE论坛
 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(初级)

5
 
自己顶起,怎么没有人啦   
此帖出自WindowsCE论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

6
 
你想得到位图文件(bmp)里面图素的一部分,那首先打开文件然后读入到内存(CreateFile和ReadFile)。

然后,你能得到文件在内存里面的指针(ReadFile的参数2输出),姑且叫pfile,类型转换成BITMAPFILEHEADER *;
之后,就可以得到图素数据的指针:
pBits = (BYTE *) pfile + pfile->bfOffBits ; //这个就是图素起始位置的指针了

之后你想取哪里,就从pBits开始往后偏移就行了。

当然需要注意:
1.我这里说的位图是真彩色的,24位,没有调色盘,当然现在一般的位图也都是24位的。
2.你要清楚的是,bmp文件存图素的顺序是倒过来的,pBits处的第一个像素是图片的左下角的像素(最后一行最左边),像素的顺序是自左向右,自下向上(第二个像素是最后一行左边第二个,以此类推)。每个像素3个BYTE(仅仅指24位位图)。顺序是蓝,绿,红。
此帖出自WindowsCE论坛
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

7
 
可以参考《windows程序设计》关于位图的章节
此帖出自WindowsCE论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

8
 
谢谢nommm的指导,我再弄一下,弄好了回头再给分
此帖出自WindowsCE论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

9
 
可以留下个邮箱吗,如果可以我给我程序你看看。真心期待大侠的指点
此帖出自WindowsCE论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

10
 
缩短时间,我还是程序的前半段粘贴出来吧,麻烦了
// CPng_ce_TestDlg 消息处理程序
BOOL CPng_ce_TestDlg::OnInitDialog()
{
        CDialog::OnInitDialog();

        // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
        //  执行此操作
        SetIcon(m_hIcon, TRUE);                        // 设置大图标
        SetIcon(m_hIcon, FALSE);                // 设置小图标

        //读取png图片
        CoInitializeEx(NULL ,COINIT_MULTITHREADED);

        if(FAILED(CoCreateInstance(CLSID_ImagingFactory,NULL,CLSCTX_INPROC_SERVER,IID_IImagingFactory ,(void **) &m_pImageFactory)))
        {
                MessageBox(_T("创建COM接口失败!"));
        }

        if(!SUCCEEDED(m_pImageFactory->CreateImageFromFile(_T("\\ResidentFlash\\image.png"),&pImage)))
        {
                MessageBox(_T("从文件读取图片失败!"));
        }
        return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)
void CPng_ce_TestDlg::OnSize(UINT /*nType*/, int /*cx*/, int /*cy*/)
{
        if (AfxIsDRAEnabled())
        {
                DRA::RelayoutDialog(
                        AfxGetResourceHandle(),
                        this->m_hWnd,
                        DRA::GetDisplayMode() != DRA::Portrait ?
                        MAKEINTRESOURCE(IDD_PNG_CE_TEST_DIALOG_WIDE) :
                        MAKEINTRESOURCE(IDD_PNG_CE_TEST_DIALOG));
        }
}
#endif


void CPng_ce_TestDlg::OnPaint()
{
        CPaintDC dc(this); // device context for painting
        CRect rect;
        this->GetClientRect(&rect);//获取对话框的大小
        if(pImage!=NULL)
        {
                pImage->Draw(this->GetDC()->m_hDC ,rect,NULL);
        }
}

void CPng_ce_TestDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
        m_downX=point.x;
        m_downY=point.y;
        UpdateData(FALSE);

        if(m_Rectangle)
        {
                CPng_ce_TestDlg::OnPaint();//Invalidate();//重绘区域
                //lpData=NULL;
                m_Rectangle=FALSE;
               
        }
        CDialog::OnLButtonDown(nFlags, point);
}

void CPng_ce_TestDlg::OnMouseMove(UINT nFlags, CPoint point)
{
        //获得鼠标当前位置
        m_Rectangle=TRUE;
        m_CreateBmp=TRUE;

        m_moveX=point.x;
        m_moveY=point.y;
                 
        /*r = GetRValue(lpData[0]);
        g = GetGValue(lpData[0]);
        b = GetBValue(lpData[0]);
        r1 = GetRValue(lpData[1]);
        g1 = GetGValue(lpData[1]);
        b1 = GetBValue(lpData[1]);*/
        CClientDC dc(this);
                COLORREF ref1 = GetPixel(dc,m_downX,m_downY);
        r1 = GetRValue(ref1);
        g1 = GetGValue(ref1);
        b1 = GetBValue(ref1);
        UpdateData(FALSE);

        CDialog::OnMouseMove(nFlags, point);
}
void CPng_ce_TestDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
        CClientDC dc(this);
        CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
        //CBrush brush(RGB(123,150,200));
        CBrush *pOldBrush=dc.SelectObject(pBrush);
        CRect rect(m_downX,m_downY,m_moveX,m_moveY);

        dc.Rectangle(&rect);
        dc.SelectObject(pOldBrush);

        if(m_CreateBmp)
        {
                CFileDialog fileDlg(FALSE,_T("*.bmp"),_T("image.bmp"),OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT ,_T("Save Fiel(*.bmp)|*.bmp||"));
                if(IDOK == fileDlg.DoModal())
                {
                        CreateBMPFile(fileDlg.GetPathName().GetBuffer(MAX_PATH),rect);
                       
                }
                GetPixel1();
        }
        r=*lpbit;
        CDialog::OnLButtonUp(nFlags, point);
}
此帖出自WindowsCE论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

11
 
引用 5 楼 nommm 的回复:
你想得到位图文件(bmp)里面图素的一部分,那首先打开文件然后读入到内存(CreateFile和ReadFile)。

然后,你能得到文件在内存里面的指针(ReadFile的参数2输出),姑且叫pfile,类型转换成BITMAPFILEHEADER *;
之后,就可以得到图素数据的指针:
pBits = (BYTE *) pfile + pfile->bfOffBits ; //这个就是图……


下面是我的代码:
void CPng_ce_TestDlg::CreateBMPFile(LPTSTR pszFile,LPRECT lpRect)
{
        CClientDC dc(this);//获取对话窗口客户区
        HDC hScrDC;//创建屏幕设备描述表
        HDC hMemDC;//创建内存设备描述表
        HBITMAP hBitmap;
        HGDIOBJ hOldBitmap;
        //保存点的颜色值
              BYTE *lpBits = NULL;
        CRect rect;

        BITMAPINFO rgb24bits;

        int nX,nY,nX2,nY2;//选定区域坐标
        //int nWidth,nHeight;//对话框大小  
         int xScrn, yScrn;
       
        if(IsRectEmpty(lpRect))//确保选中区域不为空矩形
                return;
        hScrDC=dc;//获取对话框句柄
        hMemDC=CreateCompatibleDC(hScrDC);//为屏幕设备描述表创建兼容的内存设备描述表
        //获得选定的区域坐标
        nX = lpRect->left;
        nY = lpRect->top;
        nX2 = lpRect->right;
        nY2 = lpRect->bottom;
        nWidth = nX2-nX;
        nHeight= nY2-nY;

              ZeroMemory(&rgb24bits, sizeof(BITMAPINFO));
              rgb24bits.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
              rgb24bits.bmiHeader.biWidth = nWidth;
              rgb24bits.bmiHeader.biHeight = nHeight;
              rgb24bits.bmiHeader.biPlanes = 1;
              rgb24bits.bmiHeader.biBitCount = 24;//保存为24位
        rgb24bits.bmiColors[0].rgbBlue = 0;
        rgb24bits.bmiColors[0].rgbGreen = 0;
        rgb24bits.bmiColors[0].rgbRed = 0;
        rgb24bits.bmiColors[0].rgbReserved = 0;

    hBitmap = CreateDIBSection(hMemDC, (BITMAPINFO*)&rgb24bits,DIB_RGB_COLORS,(void **)&lpBits,NULL,0);
       
    hOldBitmap = SelectObject(hMemDC, hBitmap);
   
    BitBlt(hMemDC,0,0,nWidth,nHeight,hScrDC,nX,nY,SRCCOPY);
     //初始化位图文件头结构
     BITMAPFILEHEADER bmBITMAPFILEHEADER;
     ZeroMemory(&bmBITMAPFILEHEADER, sizeof(BITMAPFILEHEADER));
     bmBITMAPFILEHEADER.bfType = 0x4d42;  //bmp
     bmBITMAPFILEHEADER.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
     bmBITMAPFILEHEADER.bfSize = bmBITMAPFILEHEADER.bfOffBits + ((nWidth*nHeight)*3);

     DWORD dwNumBytes;
         //创建新位图
    HANDLE hFile = CreateFile(pszFile,GENERIC_WRITE,(DWORD) 0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
        //不为空
    if (hFile == INVALID_HANDLE_VALUE)
        return ;

        //写入头文件
    WriteFile(hFile, &bmBITMAPFILEHEADER, sizeof(BITMAPFILEHEADER), &dwNumBytes, NULL);
        //写入信息头
    WriteFile(hFile, &(rgb24bits.bmiHeader), sizeof(BITMAPINFOHEADER), &dwNumBytes, NULL);
        //写入RGB数据.CreateDIBSection返回的第四个参数是没有内容的。要向里面写入数据才可以显示图片
    WriteFile(hFile,lpBits,3*nWidth*nHeight,&dwNumBytes, NULL);

             这是我加进去的,是这样定义吗?
        BITMAPFILEHEADER *bmpFileHeader;
        ReadFile(hFile,lpBits,3*nWidth*nHeight,&dwNumBytes,NULL);
        bmpFileHeader=(BITMAPFILEHEADER *)lpBits;
        BYTE *lpbit=(BYTE *)bmpFileHeader+bmpFileHeader->bfOffBits;还是BYTE *lpbit=(BYTE *)lpbits+bmpFileHeader->bfOffBits;
              比如说 r 表示Red的,我是不是这样写byte r=*lpbit;取他的red值?

    FlushFileBuffers(hFile);
    CloseHandle(hFile);
     //删除
    DeleteObject(hMemDC);
    DeleteObject(hScrDC);
    DeleteObject(hBitmap);
    DeleteObject(hOldBitmap);
}
此帖出自WindowsCE论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

12
 
你的代码我有一点不明白,你参数传进来一个文件名,那么你是想显示此文件并取它的一部分图素吗?如果是,就别对已经存在的文件用writefile啊……,如果你显示一定要用DIB的方式,那么也应该在CreateDIBSection以后往第四个参数的指针里面传图素数据,但是我也没发现。

我的理解是这样(如果不对高人指出,但你实验一下也就知道我说的对不对了……):
CreateDIBSection函数创建了一个DIB位图对象,分配了空间并得到了两样东西,一个是返回值,表示DIB对象句柄,一个是第四个参数给的数据区域的指针。创建好了以后数据区域还没有东西,只是空间被分配了,你要往第四个参数传出的地址中写像素值。这些像素值哪里来呢?从你使用CreateFile和ReadFile打开的,文件名由参数传入的,已有的bmp文件中来,bmp的像素数据的位置按照我前面说的得到。

所以你的流程应该是:
1.创建DIB(使用CreateDIBSection),得到的第四个参数的指针我们姑且称pDibBits。
2.打开一个位图(使用CreateFile和ReadFile),按我说的方法得到像素数据的指针,姑且称pFileBits。
3.memcpy(pDibBits,pFileBits,图像大小×3像素);
4.将DIB对象选入内存设备内容,并使用BitBlt函数显示。
5.然后对于你想取的像素值,操作pDibBits和操作pFileBits现在是一样的了,当然为了节约内存,在第3步过后,第2步读入内存的bmp文件应该已经可以释放掉了。你想对DIB的数据做这样那样的事就使用pDibBits就行了。

当然我个人比较喜欢用DDB而不是DIB来显示位图(当然因为我更不会用DX……),这里不废话……因为效果是一样的,只不过创建一个DDB必须要符合系统当前的像素位数。否则显示不能。你想试试DDB的话也去参考windows程序设计,注意这一点就行了。


另:
BYTE *lpbit=(BYTE *)bmpFileHeader+bmpFileHeader->bfOffBits;还是BYTE *lpbit=(BYTE *)lpbits+bmpFileHeader->bfOffBits;
这两个都一样。
此帖出自WindowsCE论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

13
 
我的程序是这样的:首先在对话框中显示一张png图片,我是用iimage类的com接口读取的。然后截取图片中的任何一块区域,并把截取下来的图片保存为bmp图。所以就有了参数传进一个文件名,这个是用来保存截取下来的图片的路径。上面发的代码不是我写的,可以截屏并保存bmp图,我大概能看懂代码的意思。

代码中的CreateDIBSection我想只是用来为截下的图片开辟新的DIB位图空间吧。
好像BYTE *lpbit=(BYTE *)bmpFileHeader+bmpFileHeader->bfOffBits;这个会时有时无哦
~~~~~
知道的不多,现在头疼中。要多看书才行。感谢你的回答,你上面说的对我很有用,我会好好研究实验的。
此帖出自WindowsCE论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

14
 
引用 10 楼 wozhengzai512 的回复:

我的程序是这样的:首先在对话框中显示一张png图片,我是用iimage类的com接口读取的。然后截取图片中的任何一块区域,并把截取下来的图片保存为bmp图。所以就有了参数传进一个文件名,这个是用来保存截取下来的图片的路径。上面发的代码不是我写的,可以截屏并保存bmp图,我大概能看懂代码的意思。



明白你的意思了……我理解错了……
那你是说这段不是你写的代码有问题,不能实现保存bmp的功能了?
nommmeeworld@163.com,你发吧,干看也不知道问题。你自己也要一点一点排查错误。
此帖出自WindowsCE论坛
 
 
 

回复

2

帖子

0

TA的资源

禁止发言

15
 
图片是可以保存的,错误的话估计没有。我只是对函数的不了解,运用不熟练,所以在使用时才会感到一头雾水,不知从那里下手。
我发给你了。是在Vs2005上操作的。
此帖出自WindowsCE论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

16
 
引用 14 楼 wozhengzai512 的回复:

图片是可以保存的,错误的话估计没有。我只是对函数的不了解,运用不熟练,所以在使用时才会感到一头雾水,不知从那里下手。
我发给你了。是在Vs2005上操作的。


切利哦!…………………………原来没有错误啊!!!!;

……嗯,那就别改人家的代码了,回头我写个关于CreateDIBSection的解释发给你……
此帖出自WindowsCE论坛
 
 
 

回复

6

帖子

0

TA的资源

一粒金砂(初级)

17
 
好的,谢谢。发到我邮箱就可以了
此帖出自WindowsCE论坛
 
 
 

回复

1

帖子

0

TA的资源

禁止发言

18
 
我现在可以保存截取下的像素值了,不过是用GetPixel一个个保存下来的。虽然很笨,很慢,但先解决这个问题上交吧,期限已经超了。你对CreateDIBSection的解析我暂时还没有看。你说的方法我都保存了,可能是我写的程序不对或者是少了哪方面的知识,一直无法做出来,所以先不用你说的方法。待交了这份活后,再好好恶补这方面的知识,理解理解你说的方法,自己做份好的出来。
感谢各位的帮忙!
特别感谢nommm虚心教导!
此帖出自WindowsCE论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表