我正在一个有conbobox和picturebox的应用程序中工作。用户选择路径,并且conbobox将路径加载到2000个图像,并显示第一个。当用户更改conbobox的索引时,显示的图像会发生变化,但我不知道如何删除图片框中的图像。
如果我只是覆盖图像,它就不会完成这项工作,因为当我反复执行该程序时,程序因内存而崩溃。如何删除图片框内的图片?
修改 我做了一些改动,似乎无法再次重现错误..所以也许它是别的东西。但只是为了检查,这段代码是否泄漏内存?
提示:配置是一个包含一些信息的单例,在这种情况下,是图像的位置。
private: System::Void comboBox_image1_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e) {
System::String^ aux;
DIC_config* config=DIC_config::Instance();
if(config->images_path!=NULL){
aux=gcnew System::String(config->images_path);
aux=aux+"\\CAM_0\\Snap_0_0"+(this->comboBox_image1->SelectedIndex+1)+".bmp";
System::IO::FileStream^ image_file=gcnew System::IO::FileStream(aux,System::IO::FileMode::Open,System::IO::FileAccess::Read);
System::Drawing::Bitmap^ img = gcnew System::Drawing::Bitmap(image_file);
this->pictureBox_image1->Image=img;
//img->~Bitmap(); this doesnt work, deletes the image of picturebox and makes the program chrash
}
}
答案 0 :(得分:3)
您必须处理旧图像。忘记这样做可能会导致程序在垃圾收集器运行频率不足的情况下耗尽非托管内存。位图对象非常小,您可以在不触发GC的情况下分配数千个对象,但可能会为像素数据消耗大量非托管内存。使用 delete 运算符在C ++ / CLI中处理对象,它调用IDisposable :: Dispose()。
请注意您使用的FileStream也是一次性对象。这样做需要您在使用位图时保持流打开,然后关闭它。你正确地没有处理流但是忘了关闭它。太难做到,使用接受文件路径的字符串的Bitmap构造函数要容易得多,因此Bitmap类管理基础流本身。修正:
aux = config->images_path;
aux += ....;
System::Drawing::Bitmap^ img = gcnew System::Drawing::Bitmap(aux);
delete this->pictureBox_image1->Image;
this->pictureBox_image1->Image = img;
答案 1 :(得分:2)
这不起作用,因为您试图调用类的析构函数,而不是实例。此外,您不需要调用它,因为System::Drawing::Bitmap
处于垃圾收集器的控制之下,因此如果不再引用终结器(!Bitmap())将自动调用它。
如果你想在图片框中关闭它,你可以做什么
delete this->pictureBox_image1->Image;
image_file->Close(); //after closing/deleting the open bitmap
顺便说一句。你的代码不是纯c ++,而是c ++ / cli,所以我添加了标签
答案 2 :(得分:0)
首先设置一个指向Image属性的空指针并刷新pictureBox,如下所示,
pictureBox_image1->Image = nullptr;
pictureBox_image1->Refresh();