图片由另一个进程使用(layoutpanel)

时间:2018-04-02 11:54:07

标签: c# image dispose flowlayoutpanel system.io.file

所以我在填充带有图像的浮动布局面板,使用以下代码:

    private void FillPanel(string sql)
    {
        panel.Controls.Clear();

        SQLiteConnection dbConnect = new SQLiteConnection("Data Source=" + dbFullPath + ";Version=3;");
        dbConnect.Open();

        SQLiteCommand runQuery = new SQLiteCommand(sql, dbConnect);
        SQLiteDataReader reader = runQuery.ExecuteReader();

        while (reader.Read())
        {              
            PictureBox pB = new PictureBox();
            pB.Image = Image.FromFile(reader["imgPath"].ToString());
            pB.Size = new Size(100, 100);
            pB.SizeMode = PictureBoxSizeMode.StretchImage;
            pB.Padding = new Padding();
            pB.Margin = new Padding(5,5,5,5);
            pB.Name = reader["name"].ToString();
            toolTip_Main.SetToolTip(pB, pB.Name);

            pB.DoubleClick += img_DoubleClick;

            panel.Controls.Add(pB);
        }
        dbConnect.Close();

    }

如果我稍后尝试删除源图片,我会收到错误消息。

  

" image.png由另一个进程"

使用

要删除我使用以下代码的图像:

     private void Delete()
    {
            foreach (Control x in panel.Controls)
            {
                if (x is PictureBox)
                {
                    PictureBox pb = x as PictureBox;
                    string name = pb.Name;

                    DirectoryInfo pF = new DirectoryInfo(pictureFolder);
                    foreach (FileInfo file in pF.GetFiles())
                    {
                        if(file.Name == name+".png")
                        {
                            pb.InitialImage = null;
                            pb.Dispose();
                            file.Delete();
                            break;
                        }
                    }
                }
            }
     }

如果我没有用图像填充面板,我可以删除它们。 我只是不知道我还能做些什么呢?" initialimage = null' &安培; 。用于摆脱面板内的图像。

但似乎他们在某处鬼鬼祟祟。

有关于此的任何想法吗?

1 个答案:

答案 0 :(得分:2)

打开图像时要记住的基本规则是:

(如果您想知道,Image.FromFile(String filename)实际上只是new Bitmap(String filename)构造函数的包装器。我个人建议不要使用Image.FromFile,因为它会丢失更精确的Bitmap PictureBox 1}}返回对象的类型。)

至于您的问题,似乎处置pb.Image并未处理实际图像。这可以通过首先明确处理Image img = pb.Image; // Needs to happen in this order so the UI will never try to paint the disposed image pb.Image = null; if (img != null) img.Dispose(); file.Delete(); break; 来解决:

new Bitmap(Image image)

请注意,处理实际的图像框可能会导致问题;你应该首先从它的父控件中删除它,这样它就不再显示在UI上,否则你的表单将开始抛出" object dispos"例外,因为它试图绘制的控件之一无效。

解决锁定问题的另一种方法是从磁盘读取位图,使用using构造函数从中创建新的位图,然后处理从文件初始化的位图对象。执行此操作的最佳方法是使用using (Bitmap im = new Bitmap(reader["imgPath"].ToString())) pB.Image = new Bitmap(im); 指令,如下所示:

Function ExtractCap(Txt As String) As String
    Application.Volatile
    Dim i As Long

    For i = 1 To Len(Txt)
        Select Case Asc(Mid(Txt, i, 1))
            Case 65 To 90
               ExtractCap = ExtractCap & Mid(Txt, i, 1)
        End Select
    Next
End Function

通常,您应该始终清理您创建的图像对象。请注意,这实际上会在新的32bppARGB图像上绘制图像,从而丢失图像的原始格式。虽然在你的情况下,我认为这并不重要,因为它只是用于在UI上显示。 (注意,如果您确实需要图像的完整1:1数据克隆而没有任何指向流或文件的链接,则有办法执行此操作,但they're slightly more advanced。)