1

我正在一个有组合框和图片框的应用程序中工作。用户选择一个路径,组合框会加载 2000 张图像的路径,并显示第一个。当用户更改组合框的索引时,显示的图像会发生变化,但我不知道如何删除图片框中的图像。

如果我只是覆盖图像,它就无法完成这项工作,因为当我反复这样做时,程序会因为内存而崩溃。如何删除图片框内的图像?

编辑: 我做了一些更改,似乎无法再次重现该错误..所以也许是别的东西。但只是为了检查,这段代码是否泄漏内存?

提示: config 是一个单例,其中包含一些信息,在这种情况下,图像在哪里。

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
        }

     }
4

3 回答 3

3

您必须处理图像。当垃圾收集器没有足够频繁地运行时,忘记这样做可能会使您的程序耗尽非托管内存。位图对象非常小,您可以在不触发 GC 的情况下分配数千个,但会为像素数据消耗大量非托管内存。您在 C++/CLI 中使用delete运算符处理对象,它调用 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;
于 2013-03-11T11:05:17.320 回答
2

这不起作用,因为您试图调用类的析构函数,而不是实例。此外,您不需要System::Drawing::Bitmap在垃圾收集器的控制下调用它,因此如果不再引用终结器( !Bitmap() )将被自动调用。

如果你想在图片框中关闭它,你可以做什么是

delete this->pictureBox_image1->Image;
image_file->Close(); //after closing/deleting the open bitmap

顺便提一句。你的代码不是纯c++,而是c++/cli,所以我添加了标签

于 2013-03-11T11:06:20.653 回答
0

首先设置一个指向Image属性的空指针并刷新pictureBox,如下所示,

pictureBox_image1->Image = nullptr;
pictureBox_image1->Refresh();
于 2017-09-10T13:26:04.547 回答