2

I've got a bunch of images stored on disk, with the mimetype of the image stored in a database. If I want to save the image to disk I can use Image.Save(string) (or the Async version) without needing to know the MimeType of the image.

However, if I want to save to a stream (for example, Response.Body) then I have to use Image.Save(Stream, IImageEncoder).

How do I get the IImageEncoder I need to save to the stream (without just declaring that "All my images ar png/jpeg/bmp" and using e.g. JpegEncoder)?

Moose Morals
  • 1,628
  • 25
  • 32

3 Answers3

7

ImageSharp can already tell you the mimetype of the input image. With your code if the mimetype doesn't match the input stream then the decode will fail.

(Image Image, IImageFormat Format) imf = await Image.LoadWithFormatAsync(file.OnDiskFilename);

using Image img = imf.Image;
img.Save(Response.Body, imf.Format);

What we are missing however in the current API v1.0.1 is the ability to save asynchronously while passing the format. We need to add that.

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

It took a bit of messing about, but I've figured it out:

var file = ... // From DB

ImageFormatManager ifm = Configuration.Default.ImageFormatsManager;
IImageFormat format = ifm.FindFormatByMimeType(file.MimeType);
IImageDecoder decoder = ifm.FindDecoder(format);
IImageEncoder encoder = ifm.FindEncoder(format);

using Image img = await Image.LoadAsync(file.OnDiskFilename, decoder); 
// Do what you want with the Image, e.g.: img.Mutate(i => i.Resize(width.Value, height.Value)); 
Response.ContentType = format.DefaultMimeType; // In case the stored mimetype was something weird 

await img.SaveAsync(Response.Body, encoder);

(Although I'm happy to be shown a better way)

Moose Morals
  • 1,628
  • 25
  • 32
  • This looks like its for use in generate thumbnails or equivalent. You might want to rethink returning the original file format, after you have mutated it, at all... You are probably never going to want to resize a bmp and then return it in bmp format for example, in that case you would always want a nice compressed jpeg or png. – tocsoft Aug 29 '20 at 17:26
  • Maybe, although looking at my current data set I've got about 1500 jpegs and 6 pngs, and nothing else (and I don't want to be saving my pngs as jpegs, or vice versa) – Moose Morals Sep 01 '20 at 20:47
4

ImageSharp 3.0 changed the API. LoadWithFormatAsync doesn't exist any more. The new way is:

using var img = await Image.LoadAsync(file.OnDiskFilename);
await img.SaveAsync(Response.Body, img.Metadata.DecodedImageFormat!);
Chet
  • 3,461
  • 1
  • 19
  • 24