【发布时间】:2013-11-19 10:42:23
【问题描述】:
我有一个允许上传图像的 API 函数,然后它会对其进行灰度化并将其保存在文件目录中,同时将其与用户的模型相关联。
然后,我可以将background-image css 连接到代表对该特定图像的 GET 请求的 url。
一切正常,但我现在想要做的是能够即时替换该图像,但我得到一个 IOException 和消息 "The process cannot access the file '[Filepath]\\background.png' because it is being used by another process."
所以下面是我所有相关函数的代码。您会注意到虽然PutBackgroundImage 支持多个文件,但我总是将文件名设置为常量。就我的使用而言,它可能只会成为一个文件,但无论如何我可以稍后更改它。还有很多 .Dispose() 被抛来抛去,试图关闭任何锁定文件的东西!
//GET api/LeanDxSimulation/8ed5769d-9701-465d-bd7e-38493890890b/8ed5769d-9701-465d-bd7e-38493890890b/BackgroundImage/200/200
[Route("{id:guid}/{simulationId:guid}/BackgroundImage/{width:int}/{height:int}")]
public HttpResponseMessage GetBackgroundImage(Guid id, Guid simulationId, int width, int height)
{
if (id != Guid.Empty && simulationId != Guid.Empty)
{
var model = _modelRepository.GetById(id);
if (model != null)
{
if (model.ActiveSimulation.Id != simulationId) //Can't affect any non-active simulations
{
return Request.CreateResponse(HttpStatusCode.BadRequest,
"Simulation is not currently active.");
}
if (model.ActiveSimulation.Layout != string.Empty)
{
var image = GetImage(model.ActiveSimulation.Layout, width, height);
var ms = new MemoryStream();
image.Save(ms, ImageFormat.Png);
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(ms.ToArray())
};
image.Dispose();
ms.Dispose();
result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
return result;
}
}
}
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
//PUT api/LeanDxSimulation/8ed5769d-9701-465d-bd7e-38493890890b/8ed5769d-9701-465d-bd7e-38493890890b/BackgroundImage
[Route("{id:guid}/{simulationId:guid}/BackgroundImage")]
public async Task<HttpResponseMessage> PutBackgroundImage(Guid id, Guid simulationId) //Supports multiple files, but we'll likely only use it for a single file
{
if (id != Guid.Empty && simulationId != Guid.Empty)
{
var model = _modelRepository.GetById(id);
if (model != null)
{
if (model.ActiveSimulation.Id != simulationId) //Can't affect any non-active simulations
{
return Request.CreateResponse(HttpStatusCode.BadRequest,
"Simulation is not currently active.");
}
// Check if the request contains multipart/form-data.
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
var root = HttpContext.Current.Server.MapPath("~/Model_Data" + "\\" + id + "\\" + simulationId);
var provider = new MultipartFormDataStreamProvider(root);
Directory.CreateDirectory(root);
//Any and all directories in the path are created, if exists, does nothing!
try
{
var sb = new StringBuilder(); // Holds the response body
// Read the form data and return an async task.
await Request.Content.ReadAsMultipartAsync(provider);
// This illustrates how to get the form data.
foreach (var key in provider.FormData.AllKeys)
{
var strings = provider.FormData.GetValues(key);
if (strings == null) continue;
foreach (var val in strings)
{
sb.Append(string.Format("{0}: {1}\n", key, val));
}
}
// This illustrates how to get the file names for uploaded files.
foreach (var file in provider.FileData)
{
const string fileName = "background.png"; //file.Headers.ContentDisposition.FileName;
/*if (fileName.StartsWith("\"") && fileName.EndsWith("\""))
{
fileName = fileName.Trim('"');
}
if (fileName.Contains(@"/") || fileName.Contains(@"\"))
{
fileName = Path.GetFileName(fileName);
}*/
var finalFilePath = Path.Combine(root, fileName);
if (File.Exists(finalFilePath))
{
File.Delete(finalFilePath);
}
//File.Move(file.LocalFileName, finalFilePath);
sb.Append("/Model_Data" + "/" + id + "/" + simulationId + "/" + fileName);
var colorBitmap = new Bitmap(file.LocalFileName);
var bitmap = MakeGrayscale3(colorBitmap);
bitmap.Save(finalFilePath, ImageFormat.Png);
//File.Delete(file.LocalFileName);
model.ActiveSimulation.AddLayout(finalFilePath);
bitmap.Dispose();
colorBitmap.Dispose();
}
return new HttpResponseMessage
{
Content = new StringContent(sb.ToString())
};
}
catch (Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
}
return Request.CreateResponse(HttpStatusCode.NotModified);
}
[NonAction]
public static Bitmap MakeGrayscale3(Bitmap original)
{
//create a blank bitmap the same size as original
var newBitmap = new Bitmap(original.Width, original.Height);
//get a graphics object from the new image
using (var gr = Graphics.FromImage(newBitmap))
{
//create the grayscale ColorMatrix
var colorMatrix = new ColorMatrix(
new float[][]
{
new float[] {.3f, .3f, .3f, 0, 0},
new float[] {.59f, .59f, .59f, 0, 0},
new float[] {.11f, .11f, .11f, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 0, 1}
});
//create some image attributes
var attributes = new ImageAttributes();
//set the color matrix attribute
attributes.SetColorMatrix(colorMatrix);
//draw the original image on the new image
//using the grayscale color matrix
gr.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height),
0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes);
}
return newBitmap;
}
[NonAction]
public static Image GetImage(string fileLocation, int width, int height)
{
var srcImage = Image.FromFile(fileLocation);
var newImage = new Bitmap(width, height);
using (var gr = Graphics.FromImage(newImage))
{
gr.SmoothingMode = SmoothingMode.HighQuality;
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
gr.DrawImage(srcImage, new Rectangle(0, 0, width, height));
}
return newImage;
}
在上传新图片之前,我通过$('#simWindow').css('background-image', 'none'); 清除了相关 div 上的 CSS 我想知道这是否足以让我停止为我提供该图片?
任何帮助将不胜感激!
【问题讨论】:
标签: jquery asp.net image asp.net-web-api