Пример #1
0
        public async Task CreateThumbnailAsync(Stream source, string mimeType, Stream destination, ResizeOptions options,
                                               CancellationToken ct = default)
        {
            Guard.NotNull(source, nameof(source));
            Guard.NotNull(destination, nameof(destination));
            Guard.NotNull(options, nameof(options));

            if (!options.IsValid)
            {
                await source.CopyToAsync(destination, ct);

                return;
            }

            var w = options.TargetWidth ?? 0;
            var h = options.TargetHeight ?? 0;

            using (var collection = new MagickImageCollection())
            {
                await collection.ReadAsync(source, GetFormat(mimeType), ct);

                collection.Coalesce();

                foreach (var image in collection)
                {
                    var clone = image.Clone();

                    var color = options.ParseColor();

                    if (w > 0 || h > 0)
                    {
                        var isCropUpsize = options.Mode == ResizeMode.CropUpsize;

                        var resizeMode = options.Mode;

                        if (isCropUpsize)
                        {
                            resizeMode = ResizeMode.Crop;
                        }

                        if (w >= image.Width && h >= image.Height && resizeMode == ResizeMode.Crop && !isCropUpsize)
                        {
                            resizeMode = ResizeMode.BoxPad;
                        }

                        PointF?centerCoordinates = null;

                        if (options.FocusX.HasValue && options.FocusY.HasValue)
                        {
                            centerCoordinates = new PointF(
                                +(options.FocusX.Value / 2f) + 0.5f,
                                -(options.FocusY.Value / 2f) + 0.5f
                                );
                        }

                        var(size, pad) = ResizeHelper.CalculateTargetLocationAndBounds(resizeMode, new Size(image.Width, image.Height), w, h, centerCoordinates);

                        var sourceRectangle = new MagickGeometry(pad.Width, pad.Height)
                        {
                            IgnoreAspectRatio = true
                        };

                        clone.Resize(sourceRectangle);

                        image.Extent(size.Width, size.Height);

                        image.CompositeClear(color);
                        image.Composite(clone, pad.X, pad.Y, CompositeOperator.Over);
                    }
                    else
                    {
                        image.CompositeClear(color);
                        image.Composite(clone, 0, 0, CompositeOperator.Over);
                    }

                    image.AutoOrient();

                    if (options.Quality.HasValue)
                    {
                        image.Quality = options.Quality.Value;
                    }
                }

                var firstImage  = collection[0];
                var firstFormat = firstImage.Format;

                var targetFormat = options.GetFormat(firstFormat);

                await collection.WriteAsync(destination, targetFormat, ct);
            }
        }