Search code examples
asp.net-coreimagesharp

ImageSharp rotation cuts off part of the image


I'm trying to rotate an image using ImageSharp.

This is my .NET Core API code:

    public async Task<IActionResult> Rotate([FromBody] PhotoRotateViewModel model)
    {
        var photo = await _photoRepository.Get(model.PhotoId);

        if (photo != null)
        {
            byte[] imageBytes;
            HttpWebRequest imageRequest = (HttpWebRequest)WebRequest.Create(photo.imageUrl);
            WebResponse imageResponse = imageRequest.GetResponse();

            Stream responseStream = imageResponse.GetResponseStream();

            using (BinaryReader br = new BinaryReader(responseStream))
            {
                imageBytes = br.ReadBytes(500000);
                br.Close();
            }
            responseStream.Close();
            imageResponse.Close();

            var rotatedImage = RotateImage(imageBytes);


        }
        return Ok();
    }

    private byte[] RotateImage(byte[] imageInBytes)
    {
        using (var image = Image.Load(imageInBytes, out var imageFormat))
        {
            image.Mutate(x => x.Rotate(90));
            return ImageToByteArray(image, imageFormat);
        }
    }

    private byte[] ImageToByteArray(Image<Rgba32> image, IImageFormat imageFormat)
    {
        using (var ms = new MemoryStream())
        {
            image.Save(ms, imageFormat);
            return ms.ToArray();
        }
    }

It looks like the new image gets cut off.

I've attached my original image, and the result that I get

Original:

enter image description here

Rotated:

enter image description here

This appears to be happening to all the images I've tried


Solution

  • I have had a look at the api docs. of ImageSharp and it seems there is no problem either in the library or your code(the part you rotate the image). But what seems interesting to me is that when you read the bytes, you set a number for the bytes to be read. Instead of reading like this imageBytes = br.ReadBytes(500000);, try read the bytes until the end of the stream. To do that try below code.

    using (BinaryReader br = new BinaryReader(responseStream))
    {
            imageBytes = br.ReadBytes(int.MaxValue);
            br.Close();
    }
    

    Edit:

    To deal with out of memory exception and to read the file with the help of this answer or simply setting br.ReadBytes(stream.Length);.