Как заменить обслуживаемое изображение в ASP Web API 2?

0

У меня есть функция 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'); Мне интересно, может быть, этого достаточно, чтобы сказать, прекратить служить мне этот образ?

Любая помощь будет принята с благодарностью!

Теги:
image
asp.net-web-api

1 ответ

0
Лучший ответ

Я не использовал одну из переменных 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;
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню