Deleting an image in use by another process

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

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

I used the following code to overlay images. But I am having trouble deleting temp.bmp as it is being used by another process. I think this combo code still has access to the last .bmp file.

Can anyone help me with this? Thank you.

    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]);
    }
}

      

+4


source to share


3 answers


Image

implements IDisposable

, so just setting the property pictureBox.Image

to null will not free up resources (in your case, a file). Your method Combine

also leaves images open. You must call Dispose

before trying 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

      



An alternative approach (and I'm assuming you're using WinForms here, it's a little different in WPF) would be to load the bitmap from a file manually (using FromStream

). Then you can immediately close the stream 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

      

+7


source


Vesan's answer didn't work for me, so I found another solution. This way I can protect / open the image and if I want to immediately delete the image.

I used it for my dataGridView_SelectionChanged:



private void dataGridViewAnzeige_SelectionChanged(object sender, EventArgs e)
{
    var imageAsByteArray = File.ReadAllBytes(path);
    pictureBox1.Image = byteArrayToImage(imageAsByteArray);
}

public Image byteArrayToImage(byte[] byteArrayIn)
{
    MemoryStream ms = new MemoryStream(byteArrayIn);
    Image returnImage = Image.FromStream(ms);
    return returnImage;
}

      

+1


source


All of the above answers are ok, but I have a different approach. By using the abstract Image class, you won't get enough options for manipulating and resizing the image.

Rather, you do the following:

 Bitmap img = new Bitmap(item);
 img.SetResolution(100, 100);
 Image imgNew = Image.FromHbitmap(img.GetHbitmap());
 pictureBox1.Image = imgNew;
 img.Dispose();

      

0


source







All Articles