我制作了一个显示相机强度的仪表板。我的仪表板绘图功能是......
void drawImageMeter(float intensity_value,short * cambuff)
{
//Read Image function***********************
IplImage *Image;
FILE * fp;
fp=fopen("Imagebuffer.bin","rb");
short* Pattern_Data = new short[width*height];
fread(Pattern_Data,sizeof(short),width*height,fp);
fclose(fp);
Image=cvCreateImage( cvSize( width, height ), IPL_DEPTH_16S, 1 );
cvSetData(Image,Pattern_Data, sizeof(short)*width);
CvPoint minIntensityLoc, maxIntensityLoc;
double maxIntensity,minIntensity;
cvMinMaxLoc(Image, &minIntensity, &maxIntensity, &minIntensityLoc, &maxIntensityLoc, NULL);
CvPoint2D32f roiStart;
CvPoint2D32f roiEnd;
roiStart.x =(width/2)-500;
roiStart.y = 0;
roiEnd.x = (width/2)+500;
roiEnd.y = height;
int roiWidth;
int roiHeight;
roiWidth = roiEnd.x - roiStart.x;
roiHeight = roiEnd.y - roiStart.y;
cvSetImageROI(Image, cvRect(roiStart.x, roiStart.y, roiWidth, roiHeight));
IplImage *croped_image = cvCreateImage(cvGetSize(Image), IPL_DEPTH_16S,1);
cvCopy(Image, croped_image, NULL);
cvResetImageROI(Image);
//cvSaveImage("roiIMage.bmp",croped_image);
CvScalar result = cvSum(croped_image);
double sum = result.val[0];
double average = sum / (roiWidth * roiHeight);
int max_min = maxIntensity - minIntensity;
Intensity_Values values = {maxIntensity,minIntensity,average,max_min};
cvReleaseImage(&croped_image);
cvReleaseImage(&Image);
free(Pattern_Data);
if(count1 == 1)
{
count1++;
FocusExposure::label7->Text = Convert::ToString(maxIntensity);
}
FocusExposure::label14->Text = Convert::ToString(maxIntensity);
FocusExposure::label8->Text = Convert::ToString(minIntensity);
FocusExposure::label9->Text = Convert::ToString(average);
FocusExposure::label10->Text = Convert::ToString(max_min);
//******************************************
IplImage *Background=cvLoadImage("Dialer.bmp", 1);
int width,height;
width=Background->width;
height=Background->height;
if(counter==1)
{
counter++;
needle_center.x=width/2;
needle_center.y=height/2;
needle_top.x=needle_center.x;
needle_top.y=needle_center.y-140;
}
double const PI = 3.14159265358979323;
int x1 = needle_top.x;
int y1 = needle_top.y;
int x0=needle_center.x;
int y0=needle_center.y;
float angle;
CurrIntensity = maxIntensity;
angle = CurrIntensity-PreIntensity;
angle= 0.0703125f * angle;
// degrees, not radians
float radians = angle * (PI / 180.0f); // convert degrees to radians
if (current_max==1)
{
current_max++;
int N1x1 = needle_top.x;
int N1y1 = needle_top.y;
needle1_top.x = ((N1x1-x0) * cos(radians)) - ((N1y1-y0) * sin(radians)) + x0;
needle1_top.y = ((N1x1-x0) * sin(radians)) + ((N1y1-y0) * cos(radians)) + y0;
}
needle_top.x = ((x1-x0) * cos(radians)) - ((y1-y0) * sin(radians)) + x0;
needle_top.y = ((x1-x0) * sin(radians)) + ((y1-y0) * cos(radians)) + y0;
cvLine(Background, needle_center, needle1_top, CV_RGB(0, 0, 255), 1, 4, 0);
cvLine(Background, needle_center, needle_top, CV_RGB(255, 0, 0), 1, 4, 0);
FocusExposure::pictureBox1->Image= nullptr;
FocusExposure::pictureBox1->Refresh();
System::Drawing::Bitmap ^bmp = gcnew System::Drawing::Bitmap(Background->width,Background->height,Background->widthStep,System::Drawing::Imaging::PixelFormat::Format24bppRgb,(System::IntPtr)Background->imageData);
System::IntPtr hbitmap = bmp->GetHbitmap();
FocusExposure::pictureBox1->Image=FocusExposure::pictureBox1->Image->FromHbitmap(hbitmap );
delete bmp;
DeleteObject((HGDIOBJ)hbitmap );
PreIntensity = CurrIntensity;
cvReleaseImage(&Background);
}
在此功能中没有内存泄漏。当应用程序启动时它运行正常,但是经过一段时间后,一针仪表释放一个点然后红色十字标记进入pictureBox,之后就会出现异常。
我不是为什么这个例子即将到来。我也在google上搜索过这个但没找到任何解决方案。
异常即将来临......
************** Exception Text **************
System.ArgumentException: Parameter is not valid.
at System.Drawing.Image.get_RawFormat()
at System.Drawing.Graphics.DrawImage(Image image, Int32 x, Int32 y, Int32 width, Int32 height)
at System.Drawing.Graphics.DrawImage(Image image, Rectangle rect)
at System.Windows.Forms.PictureBox.OnPaint(PaintEventArgs pe)
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
************** Loaded Assemblies **************
mscorlib
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.269 (RTMGDR.030319-2600)
CodeBase: file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll
----------------------------------------
PUMA_LED_TESTER
Assembly Version: 1.0.4673.19390
Win32 Version:
CodeBase: file:///D:/VS/FK/Puma_15_10_2012/PUMA_LED_TESTER/Release/PUMA_LED_TESTER.exe
----------------------------------------
System
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.269 built by: RTMGDR
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Windows.Forms
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.278 built by: RTMGDR
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System.Drawing
Assembly Version: 4.0.0.0
Win32 Version: 4.0.30319.282 built by: RTMGDR
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
************** JIT Debugging **************
To enable just-in-time (JIT) debugging, the .config file for this
application or computer (machine.config) must have the
jitDebugging value set in the system.windows.forms section.
The application must also be compiled with debugging
enabled.
请帮我解决这个问题。
感谢。
答案 0 :(得分:2)
delete bmp;
不要销毁已分配给PictureBox :: Image属性的位图。 GDI +尝试绘制破坏的位图时会急转直下。修改hbitmap也是不合适的,它应该类似于:
// FocusExposure::pictureBox1->Image= nullptr; Not this but:
delete FocusExposure::pictureBox1->Image;
FocusExposure::pictureBox1->Image = gcnew System::Drawing::Bitmap(...);
PreIntensity = CurrIntensity;
// etc..