我的问题:有没有办法让Windows窗体在不关闭表单的情况下释放打开的图像。
我的问题:我正在使用c ++编写一个Windows窗体。我有一个程序,允许用户编辑.bmp图像。用户从dataGridView中选择他们想要编辑的图像。图像显示在dataGridView的image列中。当我将图像加载到dataGridView控件时,表单将打开图像文件并阻止进一步编辑图像文件。即使删除了dataGridView控件,也无法编辑图像文件。表单必须在释放图像文件之前完全关闭。
我的代码:
namespace EditImageTest {
public ref class Form1 : public System::Windows::Forms::Form {
public: Form1(void) {
// create an image column & dataGridView.
System::Windows::Forms::DataGridViewImageColumn^ c = gcnew System::Windows::Forms::DataGridViewImageColumn();
c->ImageLayout = System::Windows::Forms::DataGridViewImageCellLayout::Zoom;
System::Windows::Forms::DataGridView^ dgv = gcnew System::Windows::Forms::DataGridView();
// add column to dataGridView.
dgv->Columns->Add(c);
// add dataGridView to form.
this->Controls->Add(dgv);
// add .bmp image on desktop to dataGridView.
dgv->Rows>Add(System::Drawing::Image::FromFile("C:\\Users\\User\\Desktop\\1.bmp"));
// the form has now opened the .bmp image file preventing any edits on this file.
// you can not even manualy delete this file now.
// attempt to open the .bmp image for editing.
FILE* f;
fopen_s(&f,"C:\\Users\\User\\Desktop\\1.bmp","w");
if(f) {
// write garbage in the .bmp image.
fwrite("SOME TEXT",sizeof(unsigned char),9,f);
// close the .bmp image.
fclose(f);
}
}
protected: ~Form1() { if (components) { delete components; } }
private: System::ComponentModel::Container ^components;
};
}
答案 0 :(得分:1)
Image类创建一个内存映射文件,用于将位图的像素数据映射到内存中。这是有效的,它不会占用交换文件中的空间,如果RAM页面未映射,那么它们总是可以从文件中重新加载。对于位图很重要,它们可能非常大。
但MMF确实会对文件产生锁定,直到用delete运算符处理对象才会释放它。在窗口关闭之后,当然不会发生这种情况。
您可以通过制作图像的深层副本来避免这种情况,从而可以快速释放锁定。使用Bitmap(Image ^)构造函数执行此操作:
auto img = System::Drawing::Image::FromFile("C:\\Users\\User\\Desktop\\1.bmp"));
dgv->Rows>Add(gcnew Bitmap(img));
delete img;