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);
}
}
}
设计的界面如下:
运行结果如下(图片转换保存成功,但在删除原图时出现异常:文件“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;
}
运行结果如下:
在开发过程中,当多个线程使用该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));