private static void ValidateQuery(ProcessImageQuery query)
 {
     if (query.Source == null)
     {
         throw new ArgumentException("During image processing 'ProcessImageQuery.Source' must not be null.", nameof(query));
     }
 }
Exemple #2
0
 public ImageQueryCreatedEvent(ProcessImageQuery query, HttpContext httpContext, string mimeType, string extension)
 {
     Query       = query;
     HttpContext = httpContext;
     MimeType    = mimeType;
     Extension   = extension;
 }
        private static string CreateMessage(ProcessImageQuery query, Exception innerException)
        {
            var fileName = query?.FileName;

            var msg = fileName.HasValue()
                ? "Error while processing image '{0}'".FormatCurrent(fileName.NaIfEmpty())
                : "Error while processing image";

            if (innerException != null)
            {
                msg += " (" + innerException.Message + ")";
            }

            return(msg);
        }
Exemple #4
0
        protected string GetCachedImagePath(int?mediaFileId, MediaPathData data, ProcessImageQuery query = null)
        {
            string result = "";

            // xxxxxxx
            if (mediaFileId.GetValueOrDefault() > 0)
            {
                result = mediaFileId.Value.ToString(IdFormatString);
            }

            //// INFO: (mm) don't include folder id in pathes for now. It results in more complex image cache invalidation code.
            //// xxxxxxx-f
            //if (data.Folder != null)
            //{
            //	result = result.Grow(data.Folder.Id.ToString(CultureInfo.InvariantCulture), "-");
            //}

            // xxxxxxx-f-abc
            result = result.Grow(data.FileTitle, "-");

            if (result.IsEmpty())
            {
                // files without name? No way!
                return(null);
            }

            if (query != null && query.NeedsProcessing())
            {
                // xxxxxxx-f-abc-w100-h100
                result += query.CreateHash();
            }

            if (_mediaSettings.MultipleThumbDirectories && result.Length > MaxDirLength)
            {
                // Get the first four letters of the file name
                // 0001/xxxxxxx-f-abc-w100-h100
                var subDirectoryName = result.Substring(0, MaxDirLength);
                result = subDirectoryName + "/" + result;
            }

            // 0001/xxxxxxx-f-abc-w100-h100.png
            return(result.Grow(data.Extension, "."));
        }
 public ProcessImageException(ProcessImageQuery query, Exception innerException)
     : base(CreateMessage(query, innerException), innerException)
 {
     Query = query;
 }
 public ProcessImageException(string message, ProcessImageQuery query)
     : base(message)
 {
     Query = query;
 }
 public ProcessImageException(ProcessImageQuery query)
     : this(query, null)
 {
 }
        public async Task <ProcessImageResult> ProcessImageAsync(ProcessImageQuery query, bool disposeOutput = true)
        {
            Guard.NotNull(query, nameof(query));

            ValidateQuery(query);

            var  watch = new Stopwatch();
            long len;
            IProcessableImage image = null;

            try
            {
                watch.Start();

                var source = query.Source;

                // Load source
                if (source is byte[] b)
                {
                    using var memStream = new MemoryStream(b);
                    image = await Factory.LoadAsync(memStream);

                    len = b.LongLength;
                }
                else if (source is Stream s)
                {
                    image = await Factory.LoadAsync(s);

                    len = s.Length;
                }
                else if (source is string str)
                {
                    str   = NormalizePath(str);
                    image = Factory.Load(str);
                    len   = (new FileInfo(str)).Length;
                }
                else if (source is IFile file)
                {
                    using (var fs = file.OpenRead())
                    {
                        image = await Factory.LoadAsync(fs);

                        len = file.Length;
                    }
                }
                else
                {
                    throw new ProcessImageException("Invalid source type '{0}' in query.".FormatInvariant(query.Source.GetType().FullName), query);
                }

                var sourceFormat = image.Format;

                // Pre-process event
                await _eventPublisher.PublishAsync(new ImageProcessingEvent(query, image));

                var result = new ProcessImageResult
                {
                    Query        = query,
                    SourceFormat = image.Format,
                    Image        = image,
                    DisposeImage = disposeOutput
                };

                // >>>>>> Core processing
                ProcessImageCore(query, image, out var fxApplied);

                result.HasAppliedVisualEffects = fxApplied;

                // Post-process event
                await _eventPublisher.PublishAsync(new ImageProcessedEvent(query, result));

                result.ProcessTimeMs = watch.ElapsedMilliseconds;

                return(result);
            }
            catch (Exception ex)
            {
                throw new ProcessImageException(query, ex);
            }
            finally
            {
                if (query.DisposeSource && query.Source is IDisposable source)
                {
                    source.Dispose();
                }

                watch.Stop();
                _totalProcessingTime += watch.ElapsedMilliseconds;
            }
        }
        /// <summary>
        /// Processes the loaded image. Inheritors should NOT save the image, this is done by the caller.
        /// </summary>
        /// <param name="query">Query</param>
        /// <param name="image">Image instance</param>
        /// <param name="fxApplied">
        /// Should be true if any effect has been applied that potentially changes the image visually (like background color, contrast, sharpness etc.).
        /// Resize and compression quality does NOT count as FX.
        /// </param>
        protected virtual void ProcessImageCore(ProcessImageQuery query, IProcessableImage image, out bool fxApplied)
        {
            bool fxAppliedInternal = false;

            // Resize
            var size = query.MaxWidth != null || query.MaxHeight != null
                ? new Size(query.MaxWidth ?? 0, query.MaxHeight ?? 0)
                : Size.Empty;

            image.Transform(transformer =>
            {
                if (!size.IsEmpty)
                {
                    transformer.Resize(new ResizeOptions
                    {
                        Size       = size,
                        Mode       = ProcessImageQuery.ConvertScaleMode(query.ScaleMode),
                        Position   = ProcessImageQuery.ConvertAnchorPosition(query.AnchorPosition),
                        Resampling = _mediaSettings.DefaultResamplingMode
                    });
                }

                if (query.BackgroundColor.HasValue())
                {
                    transformer.BackgroundColor(ColorTranslator.FromHtml(query.BackgroundColor));
                    fxAppliedInternal = true;
                }
            });

            fxApplied = fxAppliedInternal;

            // Format
            if (query.Format != null)
            {
                var requestedFormat = query.Format as IImageFormat;

                if (requestedFormat is null && query.Format is string queryFormat)
                {
                    requestedFormat = Factory.FindFormatByExtension(queryFormat.ToLowerInvariant());
                }

                if (requestedFormat != null && requestedFormat.DefaultMimeType != image.Format.DefaultMimeType)
                {
                    image.Format = requestedFormat;
                }
            }

            // Encoding
            if (image.Format is IJpegFormat jpegFormat)
            {
                jpegFormat.Quality   = query.Quality ?? _mediaSettings.DefaultImageQuality;
                jpegFormat.Subsample = _mediaSettings.JpegSubsampling;
            }
            else if (image.Format is IPngFormat pngFormat)
            {
                pngFormat.CompressionLevel   = _mediaSettings.PngCompressionLevel;
                pngFormat.QuantizationMethod = _mediaSettings.PngQuantizationMethod;
                pngFormat.InterlaceMode      = _mediaSettings.PngInterlaced ? PngInterlaceMode.None : PngInterlaceMode.Adam7;
                pngFormat.IgnoreMetadata     = _mediaSettings.PngIgnoreMetadata;
            }
            else if (image.Format is IGifFormat gifFormat)
            {
                gifFormat.QuantizationMethod = _mediaSettings.GifQuantizationMethod;
            }
        }
Exemple #10
0
 public ImageProcessingEvent(ProcessImageQuery query, IImage image)
 {
     Query = query;
     Image = image;
 }
Exemple #11
0
        public virtual async Task <CachedImage> GetAsync(int?mediaFileId, MediaPathData pathData, ProcessImageQuery query = null)
        {
            Guard.NotNull(pathData, nameof(pathData));

            var resultExtension = query?.GetResultExtension();

            if (resultExtension != null)
            {
                pathData.Extension = resultExtension;
            }

            var imagePath = GetCachedImagePath(mediaFileId, pathData, query);
            var file      = await _fileSystem.GetFileAsync(BuildPath(imagePath));

            var result = new CachedImage(file)
            {
                Path      = imagePath,
                Extension = pathData.Extension,
                IsRemote  = _fileSystem.StorageConfiguration.IsCloudStorage
            };

            return(result);
        }
 public ImageUploadedEvent(ProcessImageQuery query, Size size)
 {
     Query = query;
     Size  = size;
 }
Exemple #13
0
 public ImageProcessedEvent(ProcessImageQuery query, ProcessImageResult result)
 {
     Query  = query;
     Result = result;
 }