I am trying to compress image(usually around 5-30) quality / size with ImageSharp.Web() library, and I cant really understand how can I do that or what I am missing here.
Simple code example:
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.
}
I know this post is a bit old, and I'm sure that you have fixed your issue, but hopefully, it'll help some else out in the future.
Can I reuse the same memory stream / IFormFile object to save the mutated image? Or do I need to create a new Image from current image object?
You have two streams going on here, you can use one for the image from IFormFile and you can manipulate everything here, and then use your MemoryStream to save to
To work with a memory Stream do I also need to use specific JpegDecoder()?
You can save your image to the Memory Stream with .SaveAsJpeg(memoryStream)
Not sure if this line is correct item.SaveAsJpeg(memoryStream);.
You are on the right track
Maybe someone can help me out with the logic or any tips or tricks would be really helpful. Thanks!
Here is my rewrite based on what you have: Hope this helps. I'm sure there are some things that can be simplified, I tried to keep it close to OPs format
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.
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With