У меня есть функция API, которая позволяет загружать изображение, затем оно отображает его в оттенках серого и сохраняет его в каталоге файлов, сопоставляя его с моделью пользователя.
Затем я могу подключить css background-image
код background-image
к URL-адресу, представляющему запрос GET для этого конкретного изображения.
Все работает отлично, но теперь я хочу сделать это, чтобы заменить это изображение на лету, но я получаю сообщение 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');
CSS в вопросе div в вопросе $('#simWindow').css('background-image', 'none');
Мне интересно, может быть, этого достаточно, чтобы сказать, прекратить служить мне этот образ?
Любая помощь будет принята с благодарностью!
Я не использовал одну из переменных System.Drawing.Image
в моей функции GetImage()
non-action.
Я изменил его, чтобы выглядеть так:
[NonAction]
public static Image GetImage(string fileLocation, int width, int height)
{
var newImage = new Bitmap(width, height);
using (var srcImage = Image.FromFile(fileLocation))
{
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;
}