Ejemplo n.º 1
0
        public ProcessImageResult ProcessImage(ProcessImageQuery query)
        {
            Guard.NotNull(query, nameof(query));

            ValidateQuery(query);

            var watch = new Stopwatch();

            byte[] inBuffer = null;

            try
            {
                watch.Start();

                using (var processor = new ImageFactory(preserveExifData: false, fixGamma: false))
                {
                    var source = query.Source;

                    // Load source
                    if (source is byte[] b)
                    {
                        inBuffer = b;
                    }
                    else if (source is Stream s)
                    {
                        inBuffer = s.ToByteArray();
                    }
                    else if (source is Image img)
                    {
                        processor.Load(img);
                    }
                    else if (source is string str)
                    {
                        var path = NormalizePath(str);
                        using (var fs = File.OpenRead(path))
                        {
                            inBuffer = fs.ToByteArray();
                        }
                    }
                    else
                    {
                        throw new ProcessImageException("Invalid source type '{0}' in query.".FormatInvariant(query.Source.GetType().FullName), query);
                    }

                    if (inBuffer != null)
                    {
                        processor.Load(inBuffer);
                    }

                    // Pre-process event
                    _eventPublisher.Publish(new ImageProcessingEvent(query, processor));

                    var result = new ProcessImageResult
                    {
                        Query          = query,
                        SourceWidth    = processor.Image.Width,
                        SourceHeight   = processor.Image.Height,
                        SourceMimeType = processor.CurrentImageFormat.MimeType
                    };

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

                    // Create & prepare result
                    var outStream = new MemoryStream();
                    processor.Save(outStream);

                    var fmt = processor.CurrentImageFormat;
                    result.FileExtension = fmt.DefaultExtension == "jpeg" ? "jpg" : fmt.DefaultExtension;
                    result.MimeType      = fmt.MimeType;

                    result.HasAppliedVisualEffects = fxApplied;
                    result.Width  = processor.Image.Width;
                    result.Height = processor.Image.Height;

                    if (inBuffer != null)
                    {
                        // Check whether it is more beneficial to return the source instead of the result.
                        // Prefer result only if its size is smaller than the source size.
                        // Result size may be larger if a high-compressed image has been uploaded.
                        // During image processing the source compression algorithm gets lost and the image may be larger in size
                        // after encoding with default encoders.
                        var compare =
                            // only when image was not altered visually...
                            !fxApplied
                            // ...size has not changed
                            && result.Width == result.SourceWidth &&
                            result.Height == result.SourceHeight
                            // ...and format has not changed
                            && result.MimeType == result.SourceMimeType;

                        if (compare && inBuffer.LongLength <= outStream.GetBuffer().LongLength)
                        {
                            // Source is smaller. Throw away result and get back to source.
                            outStream.Dispose();
                            result.OutputStream = new MemoryStream(inBuffer, 0, inBuffer.Length, true, true);
                        }
                    }

                    // Set output stream
                    if (result.OutputStream == null)
                    {
                        result.OutputStream = outStream;
                    }

                    // Post-process event
                    _eventPublisher.Publish(new ImageProcessedEvent(query, processor, result));

                    result.OutputStream.Position = 0;

                    result.ProcessTimeMs = watch.ElapsedMilliseconds;

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

                watch.Stop();
                _totalProcessingTime += watch.ElapsedMilliseconds;
            }
        }
        public ProcessImageResult ProcessImage(ProcessImageQuery query)
        {
            Guard.NotNull(query, nameof(query));

            ValidateQuery(query);

            var watch = new Stopwatch();

            try
            {
                watch.Start();

                using (var processor = new ImageFactory(preserveExifData: false, fixGamma: false))
                {
                    var source = query.Source;

                    // Load source
                    if (source is byte[])
                    {
                        processor.Load((byte[])source);
                    }
                    else if (source is Stream)
                    {
                        processor.Load((Stream)source);
                    }
                    else if (source is Image)
                    {
                        processor.Load((Image)source);
                    }
                    else if (source is string)
                    {
                        // TODO: (mc) map virtual pathes
                        processor.Load((string)source);
                    }
                    else
                    {
                        throw new ProcessImageException("Invalid source type '{0}' in query.".FormatInvariant(query.Source.GetType().FullName), query);
                    }

                    // Pre-process event
                    _eventPublisher.Publish(new ImageProcessingEvent(query, processor));

                    var result = new ProcessImageResult
                    {
                        Query        = query,
                        SourceWidth  = processor.Image.Width,
                        SourceHeight = processor.Image.Height
                    };

                    // Core processing
                    ProcessImageCore(query, processor);

                    // Create & prepare result
                    var outStream = new MemoryStream();
                    processor.Save(outStream);

                    result.Width         = processor.Image.Width;
                    result.Height        = processor.Image.Height;
                    result.FileExtension = processor.CurrentImageFormat.DefaultExtension;
                    result.MimeType      = processor.CurrentImageFormat.MimeType;
                    result.OutputStream  = outStream;

                    // Post-process event
                    _eventPublisher.Publish(new ImageProcessedEvent(query, processor, result));

                    result.ProcessTimeMs = watch.ElapsedMilliseconds;

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

                watch.Stop();
                _totalProcessingTime += watch.ElapsedMilliseconds;
            }
        }