首页 > 解决方案 > 如何使用 ImageSharp(Web) 压缩/变异带有图像的流(IFormFile)

问题描述

我正在尝试使用ImageSharp.Web()库压缩图像(通常在 5-30 左右)质量/大小,但我无法真正理解如何做到这一点或我在这里缺少什么。

简单的代码示例:

private byte[] ConvertImageToByteArray(IFormFile inputImage)
{
    byte[] result = null;

    // filestream
    using (var fileStream = inputImage.OpenReadStream()) // IFormFile inputImage

    // memory stream
    using (var memoryStream = new MemoryStream())
    {
        fileStream.CopyTo(memoryStream);
        memoryStream.Position = 0; // The position needs to be reset.

        var before = memoryStream.Length;

        using (var item = Image.Load(memoryStream)) // do I need to use here JpegDecoder?
        {
            var beforeMutations = item.Size();

            // dummy resize options
            int width = 50;
            int height = 100;
            IResampler sampler = KnownResamplers.Lanczos3;
            bool compand = true;
            ResizeMode mode = ResizeMode.Stretch;

            // init resize object
            var resizeOptions = new ResizeOptions
            {
                Size = new Size(width, height),
                Sampler = sampler,
                Compand = compand,
                Mode = mode
            };

            // mutate image
            item.Mutate(x => x
                 .Resize(resizeOptions)
                 .Rotate(35));

            var afterMutations = item.Size();

            // try to save mutated image back to memory stream / overwrite
            // this is not overwriting memory stream
            item.SaveAsJpeg(memoryStream);

            // prepare result to byte[]
            result = memoryStream.ToArray();
        }

        var after = fileStream.Length; // kind of not needed.
        }

标签: c#asp.net-core.net-coreimagesharp

解决方案


我知道这篇文章有点老了,我相信你已经解决了你的问题,但希望它会在未来帮助其他人。

我可以重复使用相同的内存流/IFormFile 对象来保存变异的图像吗?还是我需要从当前图像对象创建一个新图像?

您在这里有两个流,您可以将一个用于 IFormFile 中的图像,您可以在此处操作所有内容,然后使用 MemoryStream 保存到

要使用内存流,我是否还需要使用特定的 JpegDecoder()?

您可以使用 .SaveAsJpeg(memoryStream) 将图像保存到内存流

不确定此行是否正确 item.SaveAsJpeg(memoryStream);。

你在正确的轨道上

也许有人可以帮助我解决逻辑,或者任何提示或技巧都会非常有帮助。谢谢!

这是我根据你所拥有的重写:希望这会有所帮助。我确定有些事情可以简化,我试图让它接近 OPs 格式

    private byte[] ConvertImageToByteArray(IFormFile inputImage)
    {
        byte[] result = null;

        // memory stream
        using (var memoryStream = new MemoryStream())
        // filestream
        using (var image = Image.Load(inputImage.OpenReadStream())) // IFormFile inputImage
        {
            //var before = memoryStream.Length; Removed this, assuming you are using for debugging?
            var beforeMutations = image.Size();

            // dummy resize options
            int width = 50;
            int height = 100;
            IResampler sampler = KnownResamplers.Lanczos3;
            bool compand = true;
            ResizeMode mode = ResizeMode.Stretch;

            // init resize object
            var resizeOptions = new ResizeOptions
            {
                Size = new Size(width, height),
                Sampler = sampler,
                Compand = compand,
                Mode = mode
            };

            // mutate image
            image.Mutate(x => x
                 .Resize(resizeOptions)
                 .Rotate(35));

            var afterMutations = image.Size();

            //Encode here for quality
            var encoder = new JpegEncoder()
            {
                Quality = 30 //Use variable to set between 5-30 based on your requirements
            };

            //This saves to the memoryStream with encoder
            image.Save(memoryStream, encoder);
            memoryStream.Position = 0; // The position needs to be reset.

            // prepare result to byte[]
            result = memoryStream.ToArray();

            var after = memoryStream.Length; // kind of not needed.
        }
    }

推荐阅读