C# 加载图片image --(C#)Image.FromFile 方法会锁住文件的原因及可能的解决方法

解决Image.FromFile文件锁定问题
Image.FromFile  一旦使用后,对应的文件在一直调用其生成的Image对象被Disponse前都不会被解除锁定,这就造成了一个问题,就是在这个图形被解锁前无法对图像进行操作(比如删除,修改等操作).


在以前用的过程中曾用过下面三个方法解决问题.


 


第一种方法,在要进行文件操作前将Image对象销毁.


PictureBox picbox;


if(picbox.Image!=null)picbox.Image.Disponse();


第二种方法,就是在加载图像的时候用一种方法替代:


System.Drawing.Image img = System.Drawing.Image.FromFile(filepath);


System.Drawing.Image bmp = new System.Drawing.Bitmap(img.Width, img.Height,    System.Drawing.Imaging.PixelFormat.Format32bppArgb);


System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmp);


g.DrawImage(img, 0, 0);


g.Flush();


g.Dispose();


img.Dispose();


//下面开始使用bmp作为显示的Image对象


System.Drawing.Image img = System.Drawing.Image.FromFile(filepath);


System.Drawing.Image bmp = new System.Drawing.Bitmap(img);


img.Dispose();


方法四:


fs = New System.IO.FileStream("C:\WINNT\Web\Wallpaper\Fly Away.jpg",
IO.FileMode.Open, IO.FileAccess.Read)
PictureBox1.Image = System.Drawing.Image.FromStream(fs)
fs.Close()


Image类的FromFile方法打开文件と后没有关闭,导致文件锁定,无法进行删除、移动等操作。


  该而使用FromStream方法,代码如下:


  //读取文件流
FileStream fileStream = new FileStream(iconPath, FileMode.Open, FileAccess.Read);


int byteLength = (int)fileStream.Length;
byte[] fileBytes = new byte[byteLength];
fileStream.Read(fileBytes, 0, byteLength);


//文件流关閉,文件解除锁定
fileStream.Close();


Pictrue.Image = Image.FromStream(new MemoryStream(fileBytes));


因为FromStream方法参数应用的流必须一直保持打开,故代码中有一个文件流向MemeoryStream流的转换,从而可以关闭文件流,保持MemoryStream流的打开状态。
<think> 我们参考了多个引用,其中提到了几种获取路径的方法,以及使用Image.FromFile加载图片时需要注意路径问题。 根据引用[1],在Web应用中,可以使用Server.MapPath("~/...")来获取绝对路径,其中"~/"表示应用程序根目录。 引用[3]和引用[5]提供了一些在桌面应用程序中获取路径的方法- 引用[3]:通过Application.ExecutablePath获取可执行文件路径,然后通过相对路径回溯(使用..\\)到项目中的图片目录。 - 引用[5]:提供了多种获取路径的方法,例如AppDomain.CurrentDomain.BaseDirectory(应用程序基目录),Application.StartupPath(启动路径)等。 根据问题描述,用户希望读取当前解决方案(项目)下的图片,也就是在项目文件夹中的图片。这里需要区分是Web应用还是桌面应用(WinForm/WPF等)。 对于Web应用(如ASP.NET): 使用Server.MapPath将虚拟路径(相对于网站根目录)转换为物理路径。 对于桌面应用(如WinForm): 通常需要获取可执行文件所在的目录,然后根据图片在项目中的位置(相对于输出目录)来构建路径。 另外,注意在桌面应用中,图片文件需要设置“复制到输出目录”属性,这样在生成项目时,图片会被复制到输出目录(如bin\Debug)中,这样程序运行时才能通过相对路径访问。 因此,我们需要根据应用类型来提供不同的解决方案。 步骤: 1. 确定应用类型(Web还是桌面)。 2. 提供相应的路径获取方法。 如果用户没有明确应用类型,我们可以分别给出两种情况的解决方案。 参考引用[5]中的方法,我们可以使用: - 在Web中:Server.MapPath("~/路径"),其中“~”表示应用程序根目录。 - 在桌面应用中:使用AppDomain.CurrentDomain.BaseDirectory获取基目录,然后拼接相对路径。 例如,在桌面应用中,如果图片位于项目中的“Images”文件夹下,并且该文件夹与可执行文件在同一目录(或者输出目录下有Images文件夹),那么可以这样写: string basePath = AppDomain.CurrentDomain.BaseDirectory; string imagePath = Path.Combine(basePath, "Images", "1.jpg"); 如果图片在项目中的位置是相对于项目根目录的,比如项目结构如下: ProjectFolder - bin - Debug - 可执行文件.exe - Images (如果设置了复制,这里会有图片) - Images (项目中的文件) - 1.jpg 那么,在生成时,需要将项目中的Images文件夹下的1.jpg复制到输出目录的Images文件夹下。可以通过设置文件的属性:复制到输出目录(Copy to Output Directory)为“始终复制”或“如果较新则复制”。 另外,引用[3]中使用了回溯的方式(..\\..\\)来获取项目目录,这种方法不太稳定,因为可执行文件的深度可能变化,所以推荐使用基目录(BaseDirectory)然后拼接。 因此,我们提供两种方案: 方案一(Web应用): string physicalPath = Server.MapPath("~/Content/imgs/defaultImg.jpeg"); Image image = Image.FromFile(physicalPath); 方案二(桌面应用): // 获取基目录 string basePath = AppDomain.CurrentDomain.BaseDirectory; // 假设图片放在输出目录下的Images文件夹中 string imagePath = Path.Combine(basePath, "Images", "1.jpg"); Image image = Image.FromFile(imagePath); 注意:在桌面应用中,需要确保图片文件被复制到输出目录。 另外,引用[4]中提到了使用Request.PhysicalApplicationPath,这是在Web中获取应用程序物理路径的方法,类似于Server.MapPath("~")。 总结: 根据不同的应用环境选择合适的方法。如果用户是在Web应用中,使用Server.MapPath;如果是在桌面应用中,使用AppDomain.CurrentDomain.BaseDirectory拼接路径。 同时,注意路径分隔符,建议使用Path.Combine来拼接,避免使用硬编码的"\\"或"/",这样能保证跨平台兼容性(虽然Windows用\\,但使用Path.Combine会自动处理)。 最后,处理文件时,最好检查文件是否存在,避免异常。 因此,完整的桌面应用示例代码: string baseDirectory = AppDomain.CurrentDomain.BaseDirectory; string imagePath = Path.Combine(baseDirectory, "Images", "1.jpg"); if (File.Exists(imagePath)) { Image image = Image.FromFile(imagePath); // 使用图片 } else { // 处理文件不存在的情况 } 如果是Web应用,通常在控制器中,可以这样写: string imagePath = Server.MapPath("~/Content/imgs/defaultImg.jpeg"); if (System.IO.File.Exists(imagePath)) { Image image = Image.FromFile(imagePath); // 使用图片 } else { // 处理文件不存在的情况 } 注意:在Web应用中,Server.MapPath需要HttpContext,在控制器中可以直接使用,如果在其他类中,可能需要通过HttpContext.Current.Server.MapPath(注意HttpContext.Current可能为null,特别是在异步等场景)。 因此,我们根据应用类型给出不同的解决方案。 </think> ### C# 使用 `Image.FromFile` 获取项目路径下图片的实现方法C# 中,使用 `Image.FromFile()` 加载项目路径下的图片时,**核心是正确获取图片的绝对物理路径**。以下是具体实现方法和注意事项: --- #### ✅ 推荐方案:动态获取项目路径 ```csharp using System.Drawing; using System.IO; // 方法1:使用应用程序基目录(推荐) string basePath = AppDomain.CurrentDomain.BaseDirectory; string imagePath = Path.Combine(basePath, "Images", "logo.png"); // 假设图片在项目\Images\logo.png // 方法2:使用启动路径(WinForm/WPF) // string startupPath = Application.StartupPath; if (File.Exists(imagePath)) { Image image = Image.FromFile(imagePath); // 使用图片... } else { throw new FileNotFoundException($"图片未找到: {imagePath}"); } ``` --- #### 📍 关键说明 1. **路径获取方式**(根据项目类型选择): - **桌面应用**(WinForm/WPF): ```csharp AppDomain.CurrentDomain.BaseDirectory // 输出目录(如\bin\Debug\) Application.StartupPath // 同上(仅限WinForm) ``` - **Web应用**(ASP.NET): ```csharp Server.MapPath("~/Content/logo.png") // 将虚拟路径转为物理路径 ``` 2. **路径拼接建议**: - 使用 `Path.Combine()` 避免路径分隔符问题(跨平台兼容) - 示例:`Path.Combine(basePath, "SubFolder", "image.jpg")` 3. **文件存在性检查**: - 必须用 `File.Exists()` 验证路径有效性,避免 `FileNotFoundException`[^1][^2] --- #### ⚠️ 常见错误及解决 1. **相对路径失效**: 直接写 `Image.FromFile("Images\logo.png")` 会失败,需转换为绝对路径[^1][^3]。 2. **路径格式问题**: - 错误:`Image.FromFile("C:\Project\Images\logo.png")`(未转义`\`) - 正确:`Image.FromFile(@"C:\Project\Images\logo.png")` 或使用 `Path.Combine` 3. **部署后路径变化**: 开发时路径(如 `\bin\Debug\`)与发布路径不同,建议使用 `BaseDirectory` 动态获取[^5]。 --- #### 📂 项目配置建议 1. **图片文件属性设置**(Visual Studio): - 右键图片 → 属性 → 复制到输出目录:选择 **始终复制** ![](https://example.com/copy-to-output.png) *确保图片被复制到生成目录* 2. **目录结构示例**: ``` 项目根目录 ├── Images │ └── logo.png // 原始文件 └── bin └── Debug └── Images └── logo.png // 自动复制的文件 ``` --- #### 🌐 不同项目类型的路径获取总结 | 项目类型 | 推荐方法 | 示例代码片段 | |----------------|-----------------------------|--------------------------------------| | WinForm/WPF | `AppDomain.CurrentDomain.BaseDirectory` | `Path.Combine(BaseDirectory, "img.png")` | | ASP.NET Web | `Server.MapPath("~/")` | `Server.MapPath("~/Content/logo.png")` | | 控制台应用 | `Directory.GetCurrentDirectory()` | `Path.Combine(Directory.GetCurrentDirectory(), "data.jpg")` | | 通用方法 | `Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)` | 需引用 `System.Reflection` | --- > **关键提示**:调试时在 `Image.FromFile()` 前添加 `Console.WriteLine(imagePath);` 输出路径,快速验证路径是否正确[^3][^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值