예제 #1
0
        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));
        }
예제 #2
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;
        }
예제 #3
0
 protected abstract Task ProcessImageAsync(MediaHandlerContext context, CachedImage cachedImage, Stream inputStream);
예제 #4
0
 protected abstract bool IsProcessable(MediaHandlerContext context);
예제 #5
0
 protected override bool IsProcessable(MediaHandlerContext context)
 {
     return(context.ImageQuery.NeedsProcessing(true) && _imageProcessor.IsSupportedImage(context.PathData.Extension));
 }