public async Task <Stream> GetAsync(IImageAssetRenderable asset, IImageResizeSettings inputSettings) { if ((inputSettings.Width < 1 && inputSettings.Height < 1) || (inputSettings.Width == asset.Width && inputSettings.Height == asset.Height)) { return(await GetFileStreamAsync(asset.ImageAssetId)); } if (_imageAssetsSettings.DisableResizing) { throw new InvalidImageResizeSettingsException("Image resizing has been requested but is disabled.", inputSettings); } var fullFileName = asset.FileNameOnDisk + "/" + CreateCacheFileName(inputSettings, asset); Stream imageStream = null; ValidateSettings(inputSettings); if (await _fileService.ExistsAsync(IMAGE_ASSET_CACHE_CONTAINER_NAME, fullFileName)) { return(await _fileService.GetAsync(IMAGE_ASSET_CACHE_CONTAINER_NAME, fullFileName)); } else { imageStream = new MemoryStream(); IImageFormat imageFormat = null; using (var originalStream = await GetFileStreamAsync(asset.ImageAssetId)) using (var image = Image.Load(originalStream, out imageFormat)) { if (imageFormat == null) { throw new Exception("Unable to determine image type for image asset " + asset.ImageAssetId); } var encoder = Configuration.Default.ImageFormatsManager.FindEncoder(imageFormat); if (encoder == null) { throw new InvalidOperationException("Encoder not found for image format " + imageFormat.Name); } var resizeOptions = ConvertSettings(inputSettings); image.Mutate(cx => { cx.Resize(resizeOptions); if (!string.IsNullOrWhiteSpace(inputSettings.BackgroundColor)) { var color = Rgba32.ParseHex(inputSettings.BackgroundColor); cx.BackgroundColor(color); } else if (CanPad(resizeOptions)) { if (SupportsTransparency(imageFormat)) { cx.BackgroundColor(Color.Transparent); encoder = EnsureEncoderSupportsTransparency(encoder); } else { // default background for jpg encoder is black, but white is a better default in most scenarios. cx.BackgroundColor(Color.White); } } }); image.Save(imageStream, encoder); } try { // Try and create the cache file, but don't throw an error if it fails - it will be attempted again on the next request await _fileService.CreateIfNotExistsAsync(IMAGE_ASSET_CACHE_CONTAINER_NAME, fullFileName, imageStream); } catch (Exception ex) { if (Debugger.IsAttached) { throw; } else { _logger.LogError(0, ex, "Error creating image asset cache file. Container name {ContainerName}, {fullFileName}", IMAGE_ASSET_CACHE_CONTAINER_NAME, fullFileName); } } imageStream.Position = 0; return(imageStream); } }