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; } }