把vc改成c++Builder 怎么会出问题,图像显示不出来. 请高手指导,谢谢.

时间:2021-11-20 02:29:25
最近在做一个摄像头的应用.
    将其中的一个vc的sdk示例程序改成cb的.
    下面是vc拍摄,显示图片的代码:
    说明:Onscreening是一个按钮的相应函数,点击后会在IDC_SHOWREGION静态文本框显示图片.

void CScrewView::OnScreening() 
{
// TODO: Add your control notification handler code here
HVSTATUS status = STATUS_OK;
CString strMsg;

/*
 * 启动数字摄像机采集序列图像到内存
 * 指定数字摄像机将图像采集到静态内存偏移为0的位置,
 *  图像在内存中的存储方式,在视频信号扫描方式为帧方式时有效
 *  TRUE 隔行存放,FALSE 奇偶场逐行存放
 */

//只定义一个缓冲区来保存图象数据
BYTE *ppBuf[1];
ppBuf[0] = m_pRawBuffer;
status = HVSnapShot(m_hhv, ppBuf, 1);

HV_VERIFY(status);

if (HV_SUCCESS(status)) {
strMsg.Format("Snap shot %d images totally to memory ", 

1);
MessageBox(strMsg, "Notice", MB_OK);

CDC *pDC = NULL;


CWnd* pWnd=GetDlgItem(IDC_SHOWREGION);


pDC = pWnd->GetDC();
ASSERT(pDC);


// 将原始图像数据进行Bayer转换,转换后为24位。
//同时将原始数据进行上下翻转


ConvertBayer2Rgb(m_pImageBuffer,m_pRawBuffer,Width,Height,ConvertType,m

_pLutR,m_pLutG,m_pLutB,true,Layout);

//在视图客户区显示图像
StretchDIBits(pDC->GetSafeHdc(),
0,
0,
Width, //显示窗口宽度
Height, //显示窗口高度
0,
0,
Width, //图像宽度
Height, //图像高度
m_pImageBuffer, //图像缓冲区
m_pBmpInfo, //BMP图像描述信


DIB_RGB_COLORS,
SRCCOPY
);

ReleaseDC(pDC);
}
}

vc 程序运行正常,能在IDC_SHOWREGION静态文本框中显示图像.

后改为cb的程序,改动后程序如下:
void __fastcall TForm1::Button2Click(TObject *Sender)
{
HVSTATUS status = STATUS_OK;
String strMsg;

/*
 * 启动数字摄像机采集序列图像到内存
 * 指定数字摄像机将图像采集到静态内存偏移为0的位置,
 *  图像在内存中的存储方式,在视频信号扫描方式为帧方式时有效
 *  TRUE 隔行存放,FALSE 奇偶场逐行存放
 */

//只定义一个缓冲区来保存图象数据
BYTE *ppBuf[1];
ppBuf[0] = m_pRawBuffer;
status = HVSnapShot(m_hhv, ppBuf, 1);

HV_VERIFY(status);

if (HV_SUCCESS(status)) {
      
                ShowMessage("拍摄了一张照片");


// 将原始图像数据进行Bayer转换,转换后为24位。
//同时将原始数据进行上下翻转


ConvertBayer2Rgb(m_pImageBuffer,m_pRawBuffer,Width0,Height0,ConvertType,m_pLutR,m_pLutG,m_pLutB,t

rue,Layout);

              
                HDC hDC = GetDC(Image3->Canvas->Handle);
       //在视图客户区显示图像
//StretchDIBits(pDC->GetSafeHdc(),
                StretchDIBits(hDC,
0,
0,
Image3->Width, //显示窗口宽度
Image3->Height, //显示窗口高度
0,
0,
Width0, //图像宽度
Height0, //图像高度
m_pImageBuffer, //图像缓冲区
m_pBmpInfo, //BMP图像描述信息
DIB_RGB_COLORS,
SRCCOPY
);

ReleaseDC(Image3->Canvas->Handle,hDC);

              


}
}

    在这Button2Click函数之前对摄像头进行了open,close操作,vc和cb的open,close摄像头操作均相同,改过后的cb程序编译通过(之前对vc的lib进行了coff2omf操作),只是运行后Timage,Image3控件不能显示图像,只要白白的一块.why?

    本人为新手,最近才上csdn,分不多,还请各位大侠多多指导.

16 个解决方案

#1


帮楼主顶一下!

#2


直接用handle操作行不行啊!不用HDC
StretchDIBits(Form->Handle,
0,
0,
Image3->Width, //显示窗口宽度
Image3->Height, //显示窗口高度
0,
0,
Width0, //图像宽度
Height0, //图像高度
m_pImageBuffer, //图像缓冲区
m_pBmpInfo, //BMP图像描述信息
DIB_RGB_COLORS,
SRCCOPY
);

#3


另外,我的经验是直接从DLL中用implib.exe生成.lib文件,
而不是用coff2omf转lib文件。

#4


HDC hDC = Image3->Canvas->Handle; //这里修改了
//在视图客户区显示图像
//StretchDIBits(pDC->GetSafeHdc(),
StretchDIBits(hDC,
0,
0,
Image3->Width, //显示窗口宽度
Image3->Height, //显示窗口高度
0,
0,
Width0, //图像宽度
Height0, //图像高度
m_pImageBuffer, //图像缓冲区
m_pBmpInfo, //BMP图像描述信息
DIB_RGB_COLORS,
SRCCOPY
);
Image3->Repaint();

#5


问题是,我只有lib文件,没有dll文件,  这样也可以用implib.exe生成.lib文件吗?

#6


按照cczlp(不惑) 朋友说的改动之后,有所改进.
在Image3上的顶部大约10分之一能显示部分图像,然后再按下拍摄按钮(即Button2Click),Image3变白.
然后,我将Image3->Repaint();注释掉.
便始终只显示10分之一的图像.

#7


看看你的m_pBmpInfo相关信息,贴出来

#8


不好意思,能告诉我怎么贴吗?

#9


回 zhangmin2000(csdnfan) 朋友:
打开摄像头函数如下:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
//设置Width,Height 大小

  Width0=300;
Height0=280;
// TODO: Add your control notification handler code here

// 打开数字摄像机 1
HVSTATUS status = BeginHVDevice(1, &m_hhv);
// 检验函数执行状态,如果失败,则返回错误状态消息框
HV_VERIFY(status);



//
// 初始化数字摄像机硬件状态,用户也可以在其他位置初始化数字摄像机,
// 但应保证数字摄像机已经打开,建议用户在应用程序初始化时,
// 同时初始化数字摄像机硬件。
//

// 设置数字摄像机分辨率
HVSetResolution(m_hhv, Resolution);

// 采集模式,包括 CONTINUATION(连续)、TRIGGER(外触发)
HVSetSnapMode(m_hhv, SnapMode);

//  设置各个分量的增益
for (int i = 0; i < 4; i++){
HVAGCControl(m_hhv, RED_CHANNEL + i, Gain);
}

// 设置曝光时间
// 设置曝光时间
//请参考曝光系数转换公式
int nOutputWid = Width0;
double dExposure = 0;
double dTint = max((double)ExposureTint_Upper/(double)ExposureTint_Lower,MY_ZERO);
dExposure = (dTint* 24000000.0 + 180.0)/((double)nOutputWid + 244.0);
HVAECControl(m_hhv, AEC_EXPOSURE_TIME, (long)dExposure);

//  设置ADC的级别
HVADCControl(m_hhv, ADC_BITS, ADCLevel);

       //
       // 视频输出窗口,即视频输出范围,输出窗口取值范围必须在输入窗口范围以内,
       //   视频窗口左上角X坐标和窗口宽度应为4的倍数,左上角Y坐标和窗口高度应为2的倍数
       // 输出窗口的起始位置一般设置为(0, 0)即可。
       //
HVSetOutputWindow(m_hhv, XStart, YStart, Width0, Height0);

// m_pBmpInfo即指向m_chBmpBuf缓冲区,用户可以自己分配BTIMAPINFO缓冲区
m_pBmpInfo       = (BITMAPINFO *)m_chBmpBuf;
// 初始化BITMAPINFO 结构,此结构在保存bmp文件、显示采集图像时使用
m_pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
// 图像宽度,一般为输出窗口宽度
m_pBmpInfo->bmiHeader.biWidth = Width0;
// 图像宽度,一般为输出窗口高度
m_pBmpInfo->bmiHeader.biHeight = Height0;


// 以下设置一般相同,
//      对于低于8位的位图,还应设置相应的位图调色板

m_pBmpInfo->bmiHeader.biPlanes = 1;
m_pBmpInfo->bmiHeader.biBitCount = 24;
m_pBmpInfo->bmiHeader.biCompression = BI_RGB;
m_pBmpInfo->bmiHeader.biSizeImage = 0;
m_pBmpInfo->bmiHeader.biXPelsPerMeter = 0;
m_pBmpInfo->bmiHeader.biYPelsPerMeter = 0;
m_pBmpInfo->bmiHeader.biClrUsed = 0;
m_pBmpInfo->bmiHeader.biClrImportant = 0;

     //
     // 分配原始图像缓冲区,一般用来存储采集图像原始数据
     //   一般图像缓冲区大小由输出窗口大小和视频格式确定。
     //
m_pRawBuffer = new BYTE[Width0 * Height0];
assert(m_pRawBuffer);


//分配Bayer转换后图像数据缓冲

m_pImageBuffer = new BYTE[Width0 * Height0 * 3];
//assert(m_pImageBuffer);

 
// this->Invalidate();
        //Panel1->Invalidate();

        
}

#10


谢谢各位热心的朋友,虽然问题还没解决,
期待更多的朋友帮忙解决问题.
现在回去吃饭,下午继续.
谢谢

#11


Image3->Picture->Bitmap->Height=Image3->Height;
Image3->Picture->Bitmap->Width=Image3->Width;

//把上面这段放在HDC hDC = Image3->Canvas->Handle;之前

#12


回 Waiting4you(毛毛) , 试过,还是不行.
还有要说明的是:Image3的大小就是(300*280)

#13


我现在怀疑是不是链接库lib的问题?

我只有vc的lib 和.h文件,怎么将其转化为cb可用的lib文件.

#14


Image3->Picture->Bitmap的大小和Image3的大小不一样的

#15


StretchDIBits函数换成Image3->Canvas->StretchDraw试试吧

#16


谢谢各位朋友.

#1


帮楼主顶一下!

#2


直接用handle操作行不行啊!不用HDC
StretchDIBits(Form->Handle,
0,
0,
Image3->Width, //显示窗口宽度
Image3->Height, //显示窗口高度
0,
0,
Width0, //图像宽度
Height0, //图像高度
m_pImageBuffer, //图像缓冲区
m_pBmpInfo, //BMP图像描述信息
DIB_RGB_COLORS,
SRCCOPY
);

#3


另外,我的经验是直接从DLL中用implib.exe生成.lib文件,
而不是用coff2omf转lib文件。

#4


HDC hDC = Image3->Canvas->Handle; //这里修改了
//在视图客户区显示图像
//StretchDIBits(pDC->GetSafeHdc(),
StretchDIBits(hDC,
0,
0,
Image3->Width, //显示窗口宽度
Image3->Height, //显示窗口高度
0,
0,
Width0, //图像宽度
Height0, //图像高度
m_pImageBuffer, //图像缓冲区
m_pBmpInfo, //BMP图像描述信息
DIB_RGB_COLORS,
SRCCOPY
);
Image3->Repaint();

#5


问题是,我只有lib文件,没有dll文件,  这样也可以用implib.exe生成.lib文件吗?

#6


按照cczlp(不惑) 朋友说的改动之后,有所改进.
在Image3上的顶部大约10分之一能显示部分图像,然后再按下拍摄按钮(即Button2Click),Image3变白.
然后,我将Image3->Repaint();注释掉.
便始终只显示10分之一的图像.

#7


看看你的m_pBmpInfo相关信息,贴出来

#8


不好意思,能告诉我怎么贴吗?

#9


回 zhangmin2000(csdnfan) 朋友:
打开摄像头函数如下:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
//设置Width,Height 大小

  Width0=300;
Height0=280;
// TODO: Add your control notification handler code here

// 打开数字摄像机 1
HVSTATUS status = BeginHVDevice(1, &m_hhv);
// 检验函数执行状态,如果失败,则返回错误状态消息框
HV_VERIFY(status);



//
// 初始化数字摄像机硬件状态,用户也可以在其他位置初始化数字摄像机,
// 但应保证数字摄像机已经打开,建议用户在应用程序初始化时,
// 同时初始化数字摄像机硬件。
//

// 设置数字摄像机分辨率
HVSetResolution(m_hhv, Resolution);

// 采集模式,包括 CONTINUATION(连续)、TRIGGER(外触发)
HVSetSnapMode(m_hhv, SnapMode);

//  设置各个分量的增益
for (int i = 0; i < 4; i++){
HVAGCControl(m_hhv, RED_CHANNEL + i, Gain);
}

// 设置曝光时间
// 设置曝光时间
//请参考曝光系数转换公式
int nOutputWid = Width0;
double dExposure = 0;
double dTint = max((double)ExposureTint_Upper/(double)ExposureTint_Lower,MY_ZERO);
dExposure = (dTint* 24000000.0 + 180.0)/((double)nOutputWid + 244.0);
HVAECControl(m_hhv, AEC_EXPOSURE_TIME, (long)dExposure);

//  设置ADC的级别
HVADCControl(m_hhv, ADC_BITS, ADCLevel);

       //
       // 视频输出窗口,即视频输出范围,输出窗口取值范围必须在输入窗口范围以内,
       //   视频窗口左上角X坐标和窗口宽度应为4的倍数,左上角Y坐标和窗口高度应为2的倍数
       // 输出窗口的起始位置一般设置为(0, 0)即可。
       //
HVSetOutputWindow(m_hhv, XStart, YStart, Width0, Height0);

// m_pBmpInfo即指向m_chBmpBuf缓冲区,用户可以自己分配BTIMAPINFO缓冲区
m_pBmpInfo       = (BITMAPINFO *)m_chBmpBuf;
// 初始化BITMAPINFO 结构,此结构在保存bmp文件、显示采集图像时使用
m_pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
// 图像宽度,一般为输出窗口宽度
m_pBmpInfo->bmiHeader.biWidth = Width0;
// 图像宽度,一般为输出窗口高度
m_pBmpInfo->bmiHeader.biHeight = Height0;


// 以下设置一般相同,
//      对于低于8位的位图,还应设置相应的位图调色板

m_pBmpInfo->bmiHeader.biPlanes = 1;
m_pBmpInfo->bmiHeader.biBitCount = 24;
m_pBmpInfo->bmiHeader.biCompression = BI_RGB;
m_pBmpInfo->bmiHeader.biSizeImage = 0;
m_pBmpInfo->bmiHeader.biXPelsPerMeter = 0;
m_pBmpInfo->bmiHeader.biYPelsPerMeter = 0;
m_pBmpInfo->bmiHeader.biClrUsed = 0;
m_pBmpInfo->bmiHeader.biClrImportant = 0;

     //
     // 分配原始图像缓冲区,一般用来存储采集图像原始数据
     //   一般图像缓冲区大小由输出窗口大小和视频格式确定。
     //
m_pRawBuffer = new BYTE[Width0 * Height0];
assert(m_pRawBuffer);


//分配Bayer转换后图像数据缓冲

m_pImageBuffer = new BYTE[Width0 * Height0 * 3];
//assert(m_pImageBuffer);

 
// this->Invalidate();
        //Panel1->Invalidate();

        
}

#10


谢谢各位热心的朋友,虽然问题还没解决,
期待更多的朋友帮忙解决问题.
现在回去吃饭,下午继续.
谢谢

#11


Image3->Picture->Bitmap->Height=Image3->Height;
Image3->Picture->Bitmap->Width=Image3->Width;

//把上面这段放在HDC hDC = Image3->Canvas->Handle;之前

#12


回 Waiting4you(毛毛) , 试过,还是不行.
还有要说明的是:Image3的大小就是(300*280)

#13


我现在怀疑是不是链接库lib的问题?

我只有vc的lib 和.h文件,怎么将其转化为cb可用的lib文件.

#14


Image3->Picture->Bitmap的大小和Image3的大小不一样的

#15


StretchDIBits函数换成Image3->Canvas->StretchDraw试试吧

#16


谢谢各位朋友.