删除另一个进程正在使用的图像 [英] Delete an image being used by another process

查看:22
本文介绍了删除另一个进程正在使用的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 C# 编写一个 winform 应用程序来打开一个图像并在它上面覆盖另一个图像.

I am writing a winform application in C# to open an image and overlay another image on top of it.

底部图像是 .jpg,顶部图像是从 .svg 转换而来的 .bmp..jpg 和 .svg 是我想要保留在文件夹中的唯一文件..bmp 用作临时文件.

The bottom image is a .jpg and the top one is a .bmp converted from .svg. The .jpg and the .svg are the only ones I want to keep in the folder. The .bmp works as a temp.

我使用以下代码来覆盖图像.但是我无法删除 temp .bmp,因为它被另一个进程使用.我认为正是这个组合代码仍然可以访问最后一个 .bmp 文件.

I was using the following code to overlay the images. But I am having trouble to delete the temp .bmp as it is used by another process. I think it is this combine code still have access to the last .bmp file.

有人能帮我解决这个问题吗?谢谢.

Could anyone help me on this? Thanks.

    private void buttonSearch_Click(object sender, EventArgs e)
    {
        FailInfo.Text = "";

        deletebmp(strFolderPath); 

        ...

        // Check if the specified front image exists. Yes, show the file name and convert SVG to BMP. No, show the error msg.
        if (File.Exists(strFilePathF))
        {
            labelFront.Text = strFileNameF;
            var svgConvert = SvgDocument.Open(svgFilePathF);
            svgConvert.Draw().Save(bmpFilePathF);
            pictureBoxFront.Image = Image.FromFile(strFilePathF);
        }
        else
        {
            labelFront.Text = "Couldn't find the file!";
            pictureBoxFront.Image = null;
        }

        // Check if the specified back image exists. Yes, show the file name and convert SVG to BMP. No, show the error msg.   
        if (File.Exists(strFilePathBF))
        {
            labelBack.Text = strFileNameBF;
            strFilePathB = strFilePathBF;
            pictureBoxBack.Image = Image.FromFile(strFilePathB);
            labelResult.Text = "FAIL";
            labelResult.BackColor = Color.FromArgb(255, 0, 0);
            var svgConvert = SvgDocument.Open(svgFilePathBF);
            bmpFilePathB = strFolderPath + strFileNameBF + ".bmp";
            svgConvert.Draw().Save(bmpFilePathB);
            svgFilePathB = svgFilePathBF;
            inspectionres(svgFilePathB);
            labelreason.Visible = true;
        }
        else if (File.Exists(strFilePathBP))
        {
            labelBack.Text = strFileNameBP;
            strFilePathB = strFilePathBP;
            pictureBoxBack.Image = Image.FromFile(strFilePathB);
            labelResult.Text = "PASS";
            labelResult.BackColor = Color.FromArgb(0, 255, 0);
            var svgConvert = SvgDocument.Open(svgFilePathBP);
            bmpFilePathB = strFolderPath + strFileNameBP + ".bmp";
            svgConvert.Draw().Save(bmpFilePathB);
            svgFilePathB = svgFilePathBP;
            inspectionres(svgFilePathB);
            labelreason.Visible = false;
        }
        else
        {
            labelBack.Text = "Couldn't find the file!";
            pictureBoxBack.Image = null;
            labelResult.Text = "ERROR";
            labelResult.BackColor = Color.FromArgb(0, 255, 255);
            labelreason.Visible = false;
        }
    }

    //
    // Overlay the SVG file on top of the JPEG file
    //
    private Bitmap Combine(string jpegFile, string bmpFile)
    {        
        Image image1 = Image.FromFile(jpegFile);
        Image image2 = Image.FromFile(bmpFile);
        Bitmap temp = new Bitmap(image1.Width, image1.Height);

        using (Graphics g = Graphics.FromImage(temp))
        {
            g.DrawImageUnscaled(image1, 0, 0);
            g.DrawImageUnscaled(image2, 0, 0);
        }

        return temp;
    }

    //
    // Show the overlaid graphic in the picturebox
    //
    private void checkBoxOverlay_CheckedChanged(object sender, EventArgs e)
    {
        try
        {
            if (FindFront)
                if (checkBoxOverlay.Checked)
                    pictureBoxFront.Image = Combine(strFilePathF, bmpFilePathF);
                else
                    pictureBoxFront.Image = Image.FromFile(strFilePathF);
            else
                pictureBoxFront.Image = null;

            if (FindBack)
                if (checkBoxOverlay.Checked)
                    pictureBoxBack.Image = Combine(strFilePathB, bmpFilePathB);
                else
                    pictureBoxBack.Image = Image.FromFile(strFilePathB);
            else
                pictureBoxBack.Image = null;
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error loading image" + ex.Message);
        }
    }

    //
    // Option of changing the image folder
    //
    private void buttonPath_Click(object sender, EventArgs e)
    {
        FolderBrowserDialog FolderBrowserDialog1 = new FolderBrowserDialog();
        if (FolderBrowserDialog1.ShowDialog() == DialogResult.OK)
        {
            strFolderPath = FolderBrowserDialog1.SelectedPath + "\\";
        }
    }

    //
    // Pull the inspection result info from the SVG file
    //
    private void inspectionres(string filename)
    {
        XDocument document = XDocument.Load(filename);
        XElement svg_Element = document.Root;
        string sb = null;

        var faillist = (from svg_path in svg_Element.Descendants("{http://www.w3.org/2000/svg}text") select svg_path).ToList();

        foreach (var item in faillist)
        {
            sb += item.ToString();
        }
    }

    //
    // Delete all the .bmp files generated from .svg files
    //
    private void deletebmp(string path)
    {
        // Unload the images from the picturebox if applicable
        pictureBoxFront.Image = null;
        pictureBoxBack.Image = null;

        string[] files = Directory.GetFiles(path, "*.bmp");
        for (int i = 0; i < files.Length; i ++ )
            File.Delete(files[i]);
    }
}

推荐答案

Image 实现了 IDisposable,所以只需设置 pictureBox.Image 属性为 null 不会释放资源(在您的情况下,是文件).您的 Combine 方法也会使图像保持打开状态.您必须在尝试删除文件之前调用 Dispose:

Image implements IDisposable, so simply setting the pictureBox.Image property to null will not release resources (in your case, the file). Your Combine method also leaves the images open. You have to call Dispose before attempting to delete the file:

Image image1 = Image.FromFile(path1);
File.Delete(path1);  // error - file is locked 

Image image2 = Image.FromFile(path2);
image2.Dispose();
File.Delete(path2);  // works

另一种方法(我假设您在这里使用的是 WinForms,在 WPF 中它有点不同)是手动从文件加载位图(使用 FromStream).然后,您可以立即关闭流并删除文件:

An alternative approach (and I assume you're using WinForms here, in WPF it's a little different) would be to load the bitmap from the file manually (using FromStream). Then, you can close the stream immediately and delete the file:

Image image;
using (Stream stream = File.OpenRead(path))
{
    image = System.Drawing.Image.FromStream(stream);
}
pictureBox.Image = image;
File.Delete("e:\\temp\\copy1.png");  //works

这篇关于删除另一个进程正在使用的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆