Не можете получить доступ к закрытому потоку? Как это предотвратить? - PullRequest
0 голосов
/ 24 марта 2020

Я пытаюсь запустить этот код, но я всегда получаю сообщение об ошибке "не удается получить доступ к закрытому потоку"

private MemoryStream GetBitmap(Stream stream, int width, int height)
        {
            const int size = 150;
            const int quality = 75;

            using (var image = new Bitmap(System.Drawing.Image.FromStream(stream)))
            {
                //int width, height;
                if (image.Width > image.Height)
                {
                    width = size;
                    height = Convert.ToInt32(image.Height * size / (double)image.Width);
                }
                else
                {
                    width = Convert.ToInt32(image.Width * size / (double)image.Height);
                    height = size;
                }

                var resized = new Bitmap(width, height);
                using (var graphics = Graphics.FromImage(resized))
                {
                    graphics.CompositingQuality = CompositingQuality.HighSpeed;
                    graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    graphics.CompositingMode = CompositingMode.SourceCopy;
                    graphics.DrawImage(image, 0, 0, width, height);

                    using (var output = new MemoryStream())
                    {
                        var qualityParamId = Encoder.Quality;
                        var encoderParameters = new EncoderParameters(1);
                        encoderParameters.Param[0] = new EncoderParameter(qualityParamId, quality);
                        var codec = ImageCodecInfo.GetImageDecoders()
                            .FirstOrDefault(codec => codec.FormatID == ImageFormat.Jpeg.Guid);

                        resized.Save(output, codec, encoderParameters);

                        return output;
                    }
                }
            }
        }

Не уверен, как я могу предотвратить вывод потока Streamstream из потока Stream.

РЕДАКТИРОВАТЬ После ваших предложений вот новый код

public Stream GetBitmap(Stream stream)
        {
            using (var image = SystemDrawingImage.FromStream(stream))
            {
                var scaled = ScaledSize(image.Width, image.Height, ThumbnailSize);
                var resized = new Bitmap(scaled.width, scaled.height);
                using (var graphics = Graphics.FromImage(resized))
                using (var attributes = new ImageAttributes())
                {
                    attributes.SetWrapMode(WrapMode.TileFlipXY);
                    graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    graphics.CompositingMode = CompositingMode.SourceCopy;
                    graphics.CompositingQuality = CompositingQuality.AssumeLinear;
                    graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    graphics.DrawImage(image, Rectangle.FromLTRB(0, 0, resized.Width, resized.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);

                    using (var encoderParams = new EncoderParameters(1))
                    using (var qualityParam = new EncoderParameter(Encoder.Quality, (long)Quality))
                    {
                        encoderParams.Param[0] = qualityParam;

                        var streamOutput = new MemoryStream();
                        resized.Save(streamOutput, systemDrawingJpegCodec, encoderParams);

                        return streamOutput;
                    }
                }
            }
        }

Вот метод действия контроллера

   [HttpGet("{photoId}")]
        public async Task<IActionResult> GetPhoto(intphotoId)
        {
            if (String.IsNullOrEmpty(photoid))
                return NotFound();

            var response = await _service.GetPhotoAsync(photoId);

            Response.Headers.Add("Content-Disposition", new ContentDisposition()
            {
                FileName = "test.jpg",
                Inline = true
            }.ToString());

            return File(response, "image/jpeg");

        }

1 Ответ

2 голосов
/ 24 марта 2020

Вы создаете MemoryStream в блоке использования. Когда блок выходит из области видимости, вызывается метод Dispose. Просто удалите using, чтобы он не был закрыт:

var output = new MemoryStream())

var qualityParamId = Encoder.Quality;
var encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(qualityParamId, quality);
var codec = ImageCodecInfo.GetImageDecoders()
    .FirstOrDefault(codec => codec.FormatID == ImageFormat.Jpeg.Guid);

resized.Save(output, codec, encoderParameters);

return output;

Кроме того, если вы планируете, чтобы вызывающая сторона прочитала поток, возможно, вы захотите сбросить свойство Position так что любой, кто читает с него, начинает с начала:

output.Position = 0;
return output;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...