public void PadTests2() { var source = new Size(100, 200); // 1x2 500x1000 var bounds = new Size(1000, 1000); var box = ResizeHelper.Pad(source, bounds, CropAnchor.Center, upscale: true); Assert.Equal(500d, box.Width); Assert.Equal(1000d, box.Height); Assert.Equal(0, box.Padding.Top); Assert.Equal(250, box.Padding.Right); Assert.Equal(0, box.Padding.Bottom); Assert.Equal(250, box.Padding.Left); Assert.Equal(1000d, box.OuterWidth); Assert.Equal(1000d, box.OuterHeight); box = ResizeHelper.Pad(source, bounds, Right, upscale: true); Assert.Equal(500, box.Padding.Left); Assert.Equal(0, box.Padding.Right); }
public static Pipeline From(IMediaInfo source, IReadOnlyList <IProcessor> processors) { var pipeline = new Pipeline { Source = source }; if (source.Orientation != null) { switch (source.Orientation.Value) { case ExifOrientation.FlipHorizontal: pipeline.Flip = FlipTransform.Horizontally; break; case ExifOrientation.Rotate180: pipeline.Rotate = 180; break; case ExifOrientation.FlipVertical: pipeline.Flip = FlipTransform.Vertically; break; case ExifOrientation.Transpose: pipeline.Flip = FlipTransform.Horizontally; pipeline.Rotate = 270; break; case ExifOrientation.Rotate90: pipeline.Rotate = 90; break; case ExifOrientation.Transverse: pipeline.Flip = FlipTransform.Horizontally; pipeline.Rotate = 90; break; case ExifOrientation.Rotate270: pipeline.Rotate = 270; break; } } var interpolater = InterpolaterMode.Lanczos3; var encodingFlags = EncodeFlags.None; Rectangle?crop = null; var box = new PaddedBox(source.Width, source.Height); int?quality = null; foreach (var transform in processors) { if (transform is PageFilter page) { pipeline.Extract = new ExtractFilter(ExtractFilterType.Page, page.Number); } else if (transform is FrameFilter frame) { pipeline.Extract = new ExtractFilter(frame.Number == 0 ? ExtractFilterType.Poster : ExtractFilterType.Frame, frame.Number); } else if (transform is TimeFilter timestamp) { pipeline.Extract = new ExtractFilter(ExtractFilterType.Time, timestamp.Value); } else if (transform is BackgroundFilter background) { pipeline.Background = background.Color; } else if (transform is FlipTransform flip) { // Do we need to apply the operations in reverse? pipeline.Flip = flip; } else if (transform is CropTransform ct) { // Note: We may have applied a scaling operating before the crop double xScale = (double)pipeline.Source.Width / box.Width; double yScale = (double)pipeline.Source.Height / box.Height; var c = ct.GetRectangle(box.Size); box.Width = c.Width; box.Height = c.Height; if (xScale != 1d || yScale != 1d) { c = c.Scale(xScale, yScale); } crop = c; } else if (transform is QualityFilter q) { quality = q.Value; } else if (transform is ResizeTransform resize) { var bounds = resize.CalcuateSize(box.Size); bool upscale = resize.Upscale; switch (resize.Mode) { case ResizeFlags.Crop: crop = ResizeHelper.CalculateCropRectangle(box.Size, bounds.ToRational(), resize.Anchor ?? CropAnchor.Center); box.Width = bounds.Width; box.Height = bounds.Height; break; case ResizeFlags.Fit: ResizeHelper.Fit(ref box, bounds, resize.Upscale); break; case ResizeFlags.Pad: box = ResizeHelper.Pad(box.Size, bounds, resize.Anchor ?? CropAnchor.Center, resize.Upscale); break; default: // Exact box.Width = bounds.Width; box.Height = bounds.Height; break; } } else if (transform is ScaleTransform scale) { box.Width = scale.Width; box.Height = scale.Height; if (scale.Mode != InterpolaterMode.None) { interpolater = scale.Mode; } } else if (transform is PadTransform pad) { box.Padding = new Padding( top: box.Padding.Top + pad.Top, right: box.Padding.Right + pad.Right, bottom: box.Padding.Bottom + pad.Bottom, left: box.Padding.Left + pad.Left ); } else if (transform is RotateTransform rotate) { if (rotate.Angle == 90 || rotate.Angle == 270) { var oldSize = box.Size; // flip the height & width box.Width = oldSize.Height; box.Height = oldSize.Width; if (crop != null) { var oldCrop = crop.Value; crop = new Rectangle(oldCrop.Y, oldCrop.X, oldCrop.Height, oldCrop.Width); } } pipeline.Rotate = rotate.Angle; } else if (transform is MetadataFilter metadata) { pipeline.Metadata = metadata; } else if (transform is LosslessFlag) { quality = 100; encodingFlags |= EncodeFlags.Lossless; } else if (transform is ExpiresFilter expires) { pipeline.Expires = expires.Timestamp; } else if (transform is EncodeParameters encode) { pipeline.Encode = quality != null || encodingFlags != default ? new EncodeParameters(encode.Format, quality, flags: encode.Flags | encodingFlags) // set the quality : encode; } else if (transform is DebugFilter) { pipeline.IsDebug = true; } else { pipeline.Filters.Add(transform); } } pipeline.Crop = crop; if ((crop is null || crop.Value.Size != box.Size) && box.OuterWidth > 0 && box.OuterHeight > 0) { pipeline.Scale = new ScaleTransform(box.Size, interpolater); } pipeline.Padding = box.Padding; return(pipeline); }