欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-07-16 19:13:47
...

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#中操作图片出现资源被占用
运行结果如下(图片转换保存成功,但在删除原图时出现异常:文件“L:\Code\WindowsFormsApplication2\1.bmp”正由另一进程使用,因此该进程无法访问此文件。):
C#中操作图片出现资源被占用
原因是用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#中操作图片出现资源被占用
C#中操作图片出现资源被占用

在开发过程中,当多个线程使用该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));