1

I am trying to take an image, resize it with ImageSharp via image.Mutate, save it to a stream, and return the image as a file via mvc controller to an Angular client. This is my code I am using to alter the image:

    public static MemoryStream ImageResizeStream(byte[] data, int maxHeight, int maxWidth, bool keepIfLower, string extension)
    {
        var size = new ImageSize();
        using (var image = Image.Load(data))
        {
            size.Height = image.Height;
            size.Width = image.Width;
        }

        ImageSize newSize = ScaleSize(size, maxWidth, maxHeight);

        var newStream = new MemoryStream();
        try
        {
            using (var image = Image.Load(data))
            {
                image.Mutate(x => x
                    .Resize(newSize.Width, newSize.Height));
                image.Save(newStream, GetImageEncoder(extension));
            }
            return newStream;
        }
        catch (Exception exception)
        {
            Console.Write(exception.Message);
        }

        return null;
    }
    public class ImageSize
    {
      public ImageSize()
      {

      }

      public ImageSize(int width, int height)
      {
          Width = width;
          Height = height;
      }
      public int Height { get; set; }
      public int Width { get; set; }
    }

And this is the controller action code that uses it: (AlterImage is the class returning the stream)

    private FileStreamResult SetResult(SystemLogo logo)
    {
        var logoExtension = logo.FileName.Split('.').Last();

        var fileType = string.Empty;

        switch (logoExtension)
        {
            case "png":
                fileType = "image/png";
                break;
            case "jpg":
                fileType = "image/jpg";
                break;
            case "gif":
                fileType = "image/gif";
                break;
        }

        //var maxHeight = 38;
        //var maxWidth = 100;
        var newStream = AlterImage.ImageResizeStream(logo.Content, 38, 100, true, logoExtension);

        var result = File(newStream, fileType);
        return result;
    }

(I return this as the result of the action)

On the client, it is getting a 500 error that I have not been able to track as of yet. Is there something I am missing here?

Jason Ward
  • 125
  • 2
  • 11
  • What line triggers the error? Have you configured your web site to return error details to help you diagnose the problem? – Jasen Nov 02 '18 at 18:54
  • So, as of right now, I do not have any idea of where the error is being triggered. My site normally catches errors, but due to the way I am using the image, it bypasses the normal httpClient requests i use for everything else, and calls the api method directly as the url of the image. – Jason Ward Nov 02 '18 at 18:59
  • I have set breakpoints throughout this code, but nothing actually gives me an exception inside the methods – Jason Ward Nov 02 '18 at 19:01
  • So you've stepped through the code and it doesn't fail until after the return? Have you tried resetting the stream position to 0 and removed the `usings` to debug if a resource has been disposed? – Jasen Nov 02 '18 at 19:32

1 Answers1

3

You need to set the stream position to 0 when passing a stream to a FileResult.

On top of that I can see some other issues (not related to your problem but not good either)

  • You don't need the ImageSize class. There's already a Size struct in the SixLabors.Primitives namespace that is a property of the Image<TPixel> class.

  • You're loading the image twice! You don't need to do that. Use the Size property inside the second using to calculate your new dimensions.

  • You're calculating the mimetypes and choosing the encoder manually. Image.Load has an overload that gives you an out IImageFormat parameter. That contains an encoder, extension, plus the mimetype.

I'm curious about your SystemLogo class also. That the Content property is a byte[] strongly suggests to e you are using ToArray() somewhere when populating that object. If so, that's adding overhead you should try and avoid. Use streams to pass data instead.

James South
  • 10,147
  • 4
  • 59
  • 115