C#中操作图片出现资源被占用

C#中操作图片出现资源被占用

用Image.FromFile读取图片后对图片进行其他操作时会出现IOException:“文件正由另一进程使用,因此该进程无法访问此文件”,可使用文件流读取图片解决该异常。
程序示例如下:
用VS2012新建一个winform程序,名为WindowsFormsApplication2,实现的功能为点击按钮,将指定路径下的bmp图片转换为jpg图片保存到相同路径下,保存之后将原bmp图删除并将生成的jpg图片设置为画板panel1的背景图片

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Drawing;
using System.IO;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

       //将bmp图片转换为jpg格式
        public string BmpToJpg(string path)
        {
            ImageCodecInfo[] vImageCodecInfos = ImageCodecInfo.GetImageEncoders();
            Bitmap vBitMap = new Bitmap(path);
            string jpgPath = null;
            foreach (ImageCodecInfo vImageCodecInfo in vImageCodecInfos)
            {
                if (vImageCodecInfo.FormatDescription.ToLower() == "jpeg")
                {
                    EncoderParameters vEncoderParameters = new EncoderParameters(1);
                    vEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 75L);
                    vBitMap.Save("L:\\Code\\WindowsFormsApplication2\\1.jpg", vImageCodecInfo, vEncoderParameters);
                    jpgPath = "L:\\Code\\WindowsFormsApplication2\\1.jpg";
                    if (File.Exists(path))
                    {
                        File.Delete(path);
                    }
                    break;
                }
            }
            return jpgPath;
        }

        private void button1_Click(object sender, System.EventArgs e)
        {
            string path = "L:\\Code\\WindowsFormsApplication2\\1.bmp";
            string JpgPath = BmpToJpg(path);
            panel1.BackgroundImage = Image.FromFile(JpgPath);
        }
    }
}

设计的界面如下:
C#中操作图片出现资源被占用_第1张图片
运行结果如下(图片转换保存成功,但在删除原图时出现异常:文件“L:\Code\WindowsFormsApplication2\1.bmp”正由另一进程使用,因此该进程无法访问此文件。):
这里写图片描述
原因是用Bitmap读取图片时会一直占用图片资源导致其他操作无法访问到该图片。解决方法:
在delete图片前加上代码vBitMap.Dispose()释放被锁定的资源即可

public string BmpToJpg(string path)
        {
            ImageCodecInfo[] vImageCodecInfos = ImageCodecInfo.GetImageEncoders();
            Bitmap vBitMap = new Bitmap(path);
            string jpgPath = null;
            foreach (ImageCodecInfo vImageCodecInfo in vImageCodecInfos)
            {
                if (vImageCodecInfo.FormatDescription.ToLower() == "jpeg")
                {
                    EncoderParameters vEncoderParameters = new EncoderParameters(1);
                    vEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 75L);
                    vBitMap.Save("L:\\Code\\WindowsFormsApplication2\\1.jpg", vImageCodecInfo, vEncoderParameters);
                    jpgPath = "L:\\Code\\WindowsFormsApplication2\\1.jpg";
                    vBitMap.Dispose(); //释放图片资源
                    if (File.Exists(path))
                    {
                        File.Delete(path);
                    }
                    break;
                }
            }
            return jpgPath;
        }

运行结果如下:
C#中操作图片出现资源被占用_第2张图片
C#中操作图片出现资源被占用_第3张图片

在开发过程中,当多个线程使用该jpg图片时也会出现资源被占用的异常情况,这是因为Image.FromFile方法读取图片会一直占用图片资源,可将panel1.BackgroundImage = Image.FromFile(JpgPath)换为文件流方式使用图片,代码如下:

            FileStream fs = new FileStream(JpgPath, FileMode.Open, FileAccess.Read);
            int byteLength = (int)fs.Length;
            byte[] fileBytes = new byte[byteLength];
            fs.Read(fileBytes, 0, byteLength);
            fs.Close();  
            panel1.BackgroundImage = Image.FromStream(new MemoryStream(fileBytes));

你可能感兴趣的:(C#)