[英]Unable to overwrite uploaded images in C# using the Image object
I am trying to create a utility in C# using the MVC framework where a user uploads a picture which is used to crop pieces out of to be used as thumbnail icons (only one user at a time will be doing this at any given time). 我正在尝试使用MVC框架在C#中创建一个实用程序,在该实用程序中,用户上传一张图片,该图片用于裁剪片段以用作缩略图图标(在任何给定的时间一次只有一个用户会这样做)。 The user can then upload a different picture and continue cropping.
然后,用户可以上传其他图片并继续裁剪。
I have a controller action that handles the file upload taking the picture, converting it from whatever format it's in to a jpeg and saving it as "temp.jpg" (I know it's not a thin controller, but this is just for testing purposes). 我有一个控制器操作,用于处理拍摄照片的文件上传,将其从格式转换为jpeg并将其保存为“ temp.jpg”(我知道它不是瘦控制器,但这只是出于测试目的) 。 When they upload the next picture I want to replace that temp.jpg with this new image.
当他们上传下一张图片时,我想用新图像替换该temp.jpg。 This controller works fine in development on my machine, but in production after the user uploads the first image and tries to replace it with another image they get the following error:
该控制器在我的机器上进行开发时工作正常,但是在用户上载第一个图像并尝试将其替换为另一个图像后,在生产环境中出现以下错误:
"the process cannot access the file because it is being used by another process" “该进程无法访问该文件,因为它正在被另一个进程使用”
It seems to me the the "temp.jpg" file is being locked after the first upload and I can't figure out how to avoid this. 在我看来,“ temp.jpg”文件在首次上传后被锁定了,我想不出如何避免这种情况。
Any suggestions or alternative ideas are welcome. 欢迎任何建议或替代想法。
Break down of what my code does: 细分我的代码的作用:
My Code: 我的代码:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult PicUpload(DateTime sd, FormCollection collection)
{
foreach (string file in Request.Files)
{
HttpPostedFileBase hpf = Request.Files[file] as HttpPostedFileBase;
if (hpf.ContentLength == 0)
continue;
string savedFileName = Path.Combine(
AppDomain.CurrentDomain.BaseDirectory + "Content\\AdContent\\",
Path.GetFileName(hpf.FileName));
FileInfo temp = new FileInfo(savedFileName);
if (temp.Exists) temp.Delete();
hpf.SaveAs(savedFileName);
string tempFileName = AppDomain.CurrentDomain.BaseDirectory + "Content\\AdContent\\temp.jpg";
temp = new FileInfo(tempFileName);
if (temp.Exists) temp.Delete();
EncoderParameters codecParams = new EncoderParameters(1);
codecParams.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
ImageCodecInfo[] encoders;
encoders = ImageCodecInfo.GetImageEncoders();
Image newPic = Image.FromFile(savedFileName);
newPic.Save(tempFileName, encoders[1], codecParams);
newPic.Dispose();
FileInfo tmp = new FileInfo(savedFileName);
if (tmp.Exists) tmp.Delete();
return RedirectToAction("Create", new { startdate = String.Format("{0:MM-dd-yyyy}", sd) });
}
return RedirectToAction("Create", new { startdate = String.Format("{0:MM-dd-yyyy}", sd) });
}
It turns out I was not freeing the resources of the image properly in another section of my code that was returning width and height properties of the image. 事实证明,我没有在代码的另一部分中正确释放图像的资源,该部分返回了图像的width和height属性。 Also instead using the
Dispose();
也可以使用
Dispose();
method, I put the code into a "using block" instead like so: 方法,我将代码放入“ using块”中,如下所示:
using (Image newPic = Image.FromFile(savedFileName))
{
newPic.Save(tempFileName, encoders[1], codecParams);
}
This worked like a charm and I can now delete the temp.jpg file with impunity. 这就像一个咒语,我现在可以删除temp.jpg文件而不受惩罚。
使用“面板”控件,然后将其保存为BMP,PNG
You can use a uniquely named temporary file for tempFileName
instead of "temp.jpg." 您可以对
tempFileName
使用唯一命名的临时文件,而不要使用“ temp.jpg”。 System.IO.Path
has a GetTempFileName()
method that you can use for this. System.IO.Path
具有可用于此目的的GetTempFileName()
方法。
Another option would be to use the GetRandomFileName()
method (also in System.IO.Path
) which returns a random path or filename, then it's just a matter of making a small change to your code: 另一个选择是使用
GetRandomFileName()
方法(同样在System.IO.Path
),该方法返回随机路径或文件名,然后只需对代码做一些小的更改即可:
- string tempFileName = AppDomain.CurrentDomain.BaseDirectory + "Content\\AdContent\\temp.jpg";
+ string tempFileName = AppDomain.CurrentDomain.BaseDirectory + "Content\\AdContent\\" + System.IO.Path.GetRandomFileName();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.