protected override Task ProcessImageAsync(MediaHandlerContext context, CachedImage cachedImage, Stream inputStream) { var processQuery = new ProcessImageQuery(context.ImageQuery) { Source = inputStream, Format = context.ImageQuery.Format ?? cachedImage.Extension, FileName = cachedImage.FileName, DisposeSource = false }; using (var result = _imageProcessor.ProcessImage(processQuery, false)) { Logger.DebugFormat($"Processed image '{cachedImage.FileName}' in {result.ProcessTimeMs} ms.", null); if (!cachedImage.Extension.IsCaseInsensitiveEqual(result.FileExtension)) { // jpg <> jpeg cachedImage.Path = Path.ChangeExtension(cachedImage.Path, result.FileExtension); cachedImage.Extension = result.FileExtension; } context.ResultStream = result.OutputStream; } return(Task.FromResult(0)); }
public async Task ExecuteAsync(MediaHandlerContext context) { if (!IsProcessable(context)) { return; } var query = context.ImageQuery; var pathData = context.PathData; var cachedImage = ImageCache.Get(context.MediaFileId, pathData, query); if (!pathData.Extension.IsCaseInsensitiveEqual(cachedImage.Extension)) { // The query requests another format. // Adjust extension and mime type fo proper ETag creation. pathData.Extension = cachedImage.Extension; pathData.MimeType = cachedImage.MimeType; } var exists = cachedImage.Exists; if (exists && cachedImage.FileSize == 0) { // Empty file means: thumb extraction failed before and will most likely fail again. // Don't bother proceeding. context.Exception = ExceptionFactory.ExtractThumbnail(cachedImage.FileName); context.Executed = true; return; } if (!exists) { // Lock concurrent requests to same resource using (await KeyedLock.LockAsync("ImageHandlerBase.Execute." + cachedImage.Path)) { ImageCache.RefreshInfo(cachedImage); // File could have been processed by another request in the meantime, check again. if (!cachedImage.Exists) { // Call inner function var sourceFile = context.SourceFile; if (sourceFile == null || sourceFile.Size == 0) { context.Executed = true; return; } var inputStream = sourceFile.OpenRead(); if (inputStream == null) { context.Exception = ExceptionFactory.ExtractThumbnail(sourceFile.Path, T("Admin.Media.Exception.NullInputStream")); context.Executed = true; return; } try { await ProcessImageAsync(context, cachedImage, inputStream); } catch (Exception ex) { Logger.Error(ex); if (ex is ExtractThumbnailException) { // Thumbnail extraction failed and we must assume that it always will fail. // Therefore we create an empty file to prevent repetitive processing. using (var memStream = new MemoryStream()) { await ImageCache.PutAsync(cachedImage, memStream); } } context.Exception = ex; context.Executed = true; return; } finally { if (inputStream != null) { inputStream.Dispose(); } } if (context.ResultImage != null) { ImageCache.Put(cachedImage, context.ResultImage); context.ResultFile = cachedImage.File; } context.Executed = true; return; } } } // Cached image existed already context.ResultFile = cachedImage.File; context.Executed = true; }
protected abstract Task ProcessImageAsync(MediaHandlerContext context, CachedImage cachedImage, Stream inputStream);
protected abstract bool IsProcessable(MediaHandlerContext context);
protected override bool IsProcessable(MediaHandlerContext context) { return(context.ImageQuery.NeedsProcessing(true) && _imageProcessor.IsSupportedImage(context.PathData.Extension)); }