Browse Source

migrate to a Image.Generate/Image.Mutate context api

pull/275/head
Scott Williams 9 years ago
parent
commit
f026778e47
  1. 17
      samples/AvatarWithRoundedCorner/Program.cs
  2. 14
      src/ImageSharp.Drawing/DrawImage.cs
  3. 14
      src/ImageSharp.Drawing/FillRegion.cs
  4. 12
      src/ImageSharp.Drawing/Paths/DrawBeziers.cs
  5. 12
      src/ImageSharp.Drawing/Paths/DrawLines.cs
  6. 12
      src/ImageSharp.Drawing/Paths/DrawPath.cs
  7. 12
      src/ImageSharp.Drawing/Paths/DrawPathCollection.cs
  8. 12
      src/ImageSharp.Drawing/Paths/DrawPolygon.cs
  9. 12
      src/ImageSharp.Drawing/Paths/DrawRectangle.cs
  10. 8
      src/ImageSharp.Drawing/Paths/FillPathBuilder.cs
  11. 8
      src/ImageSharp.Drawing/Paths/FillPathCollection.cs
  12. 8
      src/ImageSharp.Drawing/Paths/FillPaths.cs
  13. 8
      src/ImageSharp.Drawing/Paths/FillPolygon.cs
  14. 8
      src/ImageSharp.Drawing/Paths/FillRectangle.cs
  15. 2
      src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs
  16. 21
      src/ImageSharp.Drawing/Text/DrawText.Path.cs
  17. 21
      src/ImageSharp.Drawing/Text/DrawText.cs
  18. 9
      src/ImageSharp.Drawing/Text/TextGraphicsOptions.cs
  19. 100
      src/ImageSharp/ApplyProcessors.cs
  20. 19
      src/ImageSharp/Formats/Bmp/ImageExtensions.cs
  21. 21
      src/ImageSharp/Formats/Gif/ImageExtensions.cs
  22. 21
      src/ImageSharp/Formats/Jpeg/ImageExtensions.cs
  23. 21
      src/ImageSharp/Formats/Png/ImageExtensions.cs
  24. 36
      src/ImageSharp/IImageOperations{TPixel}.cs
  25. 2
      src/ImageSharp/Image/IImageProcessor.cs
  26. 10
      src/ImageSharp/Image/ImageBase{TPixel}.cs
  27. 4
      src/ImageSharp/Image/ImageProcessingExtensions.cs
  28. 8
      src/ImageSharp/Image/Image{TPixel}.cs
  29. 62
      src/ImageSharp/ImageOperations.cs
  30. 124
      src/ImageSharp/Numerics/ValueSize.cs
  31. 7
      src/ImageSharp/Processing/Binarization/BinaryThreshold.cs
  32. 14
      src/ImageSharp/Processing/Binarization/Dither.cs
  33. 7
      src/ImageSharp/Processing/ColorMatrix/BlackWhite.cs
  34. 48
      src/ImageSharp/Processing/ColorMatrix/ColorBlindness.cs
  35. 20
      src/ImageSharp/Processing/ColorMatrix/Grayscale.cs
  36. 7
      src/ImageSharp/Processing/ColorMatrix/Hue.cs
  37. 7
      src/ImageSharp/Processing/ColorMatrix/Kodachrome.cs
  38. 13
      src/ImageSharp/Processing/ColorMatrix/Lomograph.cs
  39. 11
      src/ImageSharp/Processing/ColorMatrix/Polaroid.cs
  40. 7
      src/ImageSharp/Processing/ColorMatrix/Saturation.cs
  41. 13
      src/ImageSharp/Processing/ColorMatrix/Sepia.cs
  42. 13
      src/ImageSharp/Processing/Convolution/BoxBlur.cs
  43. 80
      src/ImageSharp/Processing/Convolution/DetectEdges.cs
  44. 13
      src/ImageSharp/Processing/Convolution/GaussianBlur.cs
  45. 13
      src/ImageSharp/Processing/Convolution/GaussianSharpen.cs
  46. 44
      src/ImageSharp/Processing/DelegateImageProcessor.cs
  47. 13
      src/ImageSharp/Processing/Effects/Alpha.cs
  48. 17
      src/ImageSharp/Processing/Effects/BackgroundColor.cs
  49. 13
      src/ImageSharp/Processing/Effects/Brightness.cs
  50. 13
      src/ImageSharp/Processing/Effects/Contrast.cs
  51. 13
      src/ImageSharp/Processing/Effects/Invert.cs
  52. 26
      src/ImageSharp/Processing/Effects/OilPainting.cs
  53. 18
      src/ImageSharp/Processing/Effects/Pixelate.cs
  54. 66
      src/ImageSharp/Processing/ImageProcessor.cs
  55. 79
      src/ImageSharp/Processing/Overlays/Glow.cs
  56. 54
      src/ImageSharp/Processing/Overlays/Vignette.cs
  57. 2
      src/ImageSharp/Processing/Processors/ColorMatrix/PolaroidProcessor.cs
  58. 5
      src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor.cs
  59. 13
      src/ImageSharp/Processing/Processors/Effects/PixelateProcessor.cs
  60. 11
      src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs
  61. 28
      src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs
  62. 103
      src/ImageSharp/Processing/Processors/Transforms/AutoRotateProcessor.cs
  63. 12
      src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.cs
  64. 64
      src/ImageSharp/Processing/Transforms/AutoOrient.cs
  65. 15
      src/ImageSharp/Processing/Transforms/Crop.cs
  66. 9
      src/ImageSharp/Processing/Transforms/EntropyCrop.cs
  67. 9
      src/ImageSharp/Processing/Transforms/Flip.cs
  68. 2
      src/ImageSharp/Processing/Transforms/Pad.cs
  69. 118
      src/ImageSharp/Processing/Transforms/Resize.cs
  70. 17
      src/ImageSharp/Processing/Transforms/Rotate.cs
  71. 2
      src/ImageSharp/Processing/Transforms/RotateFlip.cs
  72. 11
      src/ImageSharp/Processing/Transforms/Skew.cs
  73. 45
      src/ImageSharp/Quantizers/Quantize.cs
  74. 4
      tests/ImageSharp.Benchmarks/Drawing/DrawBeziers.cs
  75. 4
      tests/ImageSharp.Benchmarks/Drawing/DrawLines.cs
  76. 4
      tests/ImageSharp.Benchmarks/Drawing/DrawPolygon.cs
  77. 8
      tests/ImageSharp.Benchmarks/Drawing/FillPolygon.cs
  78. 6
      tests/ImageSharp.Benchmarks/Drawing/FillRectangle.cs
  79. 2
      tests/ImageSharp.Benchmarks/Drawing/FillWithPattern.cs
  80. 2
      tests/ImageSharp.Benchmarks/Samplers/Crop.cs
  81. 22
      tests/ImageSharp.Benchmarks/Samplers/DetectEdges.cs
  82. 2
      tests/ImageSharp.Benchmarks/Samplers/Glow.cs
  83. 2
      tests/ImageSharp.Benchmarks/Samplers/Resize.cs
  84. 12
      tests/ImageSharp.Tests/Drawing/BeziersTests.cs
  85. 42
      tests/ImageSharp.Tests/Drawing/BlendedShapes.cs
  86. 4
      tests/ImageSharp.Tests/Drawing/DrawImageTest.cs
  87. 16
      tests/ImageSharp.Tests/Drawing/DrawPathTests.cs
  88. 7
      tests/ImageSharp.Tests/Drawing/FillPatternTests.cs
  89. 6
      tests/ImageSharp.Tests/Drawing/FillRegionProcessorTests.cs
  90. 15
      tests/ImageSharp.Tests/Drawing/FillSolidBrushTests.cs
  91. 30
      tests/ImageSharp.Tests/Drawing/LineComplexPolygonTests.cs
  92. 88
      tests/ImageSharp.Tests/Drawing/LineTests.cs
  93. 8
      tests/ImageSharp.Tests/Drawing/Paths/FillPath.cs
  94. 8
      tests/ImageSharp.Tests/Drawing/Paths/FillPathCollection.cs
  95. 8
      tests/ImageSharp.Tests/Drawing/Paths/FillPolygon.cs
  96. 8
      tests/ImageSharp.Tests/Drawing/Paths/FillRectangle.cs
  97. 28
      tests/ImageSharp.Tests/Drawing/PolygonTests.cs
  98. 8
      tests/ImageSharp.Tests/Drawing/RecolorImageTest.cs
  99. 16
      tests/ImageSharp.Tests/Drawing/SolidBezierTests.cs
  100. 18
      tests/ImageSharp.Tests/Drawing/SolidComplexPolygonTests.cs

17
samples/AvatarWithRoundedCorner/Program.cs

@ -23,13 +23,14 @@ namespace AvatarWithRoundedCorner
{
using (var image = Image.Load(source))
{
image.Resize(new ImageSharp.Processing.ResizeOptions
{
Size = size,
Mode = ImageSharp.Processing.ResizeMode.Crop
});
image.Mutate(x => x
.Resize(new ImageSharp.Processing.ResizeOptions
{
Size = size,
Mode = ImageSharp.Processing.ResizeMode.Crop
})
.Run(i=>ApplyRoundedCourners(i, cornerRadius)));
ApplyRoundedCourners(image, cornerRadius);
image.Save(destination);
}
}
@ -38,10 +39,10 @@ namespace AvatarWithRoundedCorner
{
var corners = BuildCorners(img.Width, img.Height, cornerRadius);
// now we have our corners time to draw them
img.Fill(Rgba32.Transparent, corners, new GraphicsOptions(true)
img.Mutate(x => x.Fill(Rgba32.Transparent, corners, new GraphicsOptions(true)
{
BlenderMode = ImageSharp.PixelFormats.PixelBlenderMode.Src // enforces that any part of this shape that has color is punched out of the background
});
}));
}
public static IPathCollection BuildCorners(int imageWidth, int imageHeight, float cornerRadius)

14
src/ImageSharp.Drawing/DrawImage.cs

@ -24,7 +24,7 @@ namespace ImageSharp
/// <param name="location">The location to draw the blended image.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DrawImage<TPixel>(this Image<TPixel> source, Image<TPixel> image, Size size, Point location, GraphicsOptions options)
public static IImageOperations<TPixel> DrawImage<TPixel>(this IImageOperations<TPixel> source, Image<TPixel> image, Size size, Point location, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
if (size == default(Size))
@ -37,7 +37,7 @@ namespace ImageSharp
location = Point.Empty;
}
source.ApplyProcessor(new DrawImageProcessor<TPixel>(image, size, location, options), source.Bounds);
source.ApplyProcessor(new DrawImageProcessor<TPixel>(image, size, location, options));
return source;
}
@ -49,7 +49,7 @@ namespace ImageSharp
/// <param name="image">The image to blend with the currently processing image.</param>
/// <param name="percent">The opacity of the image image to blend. Must be between 0 and 1.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Blend<TPixel>(this Image<TPixel> source, Image<TPixel> image, float percent)
public static IImageOperations<TPixel> Blend<TPixel>(this IImageOperations<TPixel> source, Image<TPixel> image, float percent)
where TPixel : struct, IPixel<TPixel>
{
GraphicsOptions options = GraphicsOptions.Default;
@ -66,7 +66,7 @@ namespace ImageSharp
/// <param name="blender">The blending mode.</param>
/// <param name="percent">The opacity of the image image to blend. Must be between 0 and 1.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Blend<TPixel>(this Image<TPixel> source, Image<TPixel> image, PixelBlenderMode blender, float percent)
public static IImageOperations<TPixel> Blend<TPixel>(this IImageOperations<TPixel> source, Image<TPixel> image, PixelBlenderMode blender, float percent)
where TPixel : struct, IPixel<TPixel>
{
GraphicsOptions options = GraphicsOptions.Default;
@ -83,7 +83,7 @@ namespace ImageSharp
/// <param name="image">The image to blend with the currently processing image.</param>
/// <param name="options">The options, including the blending type and belnding amount.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Blend<TPixel>(this Image<TPixel> source, Image<TPixel> image, GraphicsOptions options)
public static IImageOperations<TPixel> Blend<TPixel>(this IImageOperations<TPixel> source, Image<TPixel> image, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return DrawImage(source, image, default(Size), default(Point), options);
@ -99,7 +99,7 @@ namespace ImageSharp
/// <param name="size">The size to draw the blended image.</param>
/// <param name="location">The location to draw the blended image.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DrawImage<TPixel>(this Image<TPixel> source, Image<TPixel> image, float percent, Size size, Point location)
public static IImageOperations<TPixel> DrawImage<TPixel>(this IImageOperations<TPixel> source, Image<TPixel> image, float percent, Size size, Point location)
where TPixel : struct, IPixel<TPixel>
{
GraphicsOptions options = GraphicsOptions.Default;
@ -118,7 +118,7 @@ namespace ImageSharp
/// <param name="size">The size to draw the blended image.</param>
/// <param name="location">The location to draw the blended image.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DrawImage<TPixel>(this Image<TPixel> source, Image<TPixel> image, PixelBlenderMode blender, float percent, Size size, Point location)
public static IImageOperations<TPixel> DrawImage<TPixel>(this IImageOperations<TPixel> source, Image<TPixel> image, PixelBlenderMode blender, float percent, Size size, Point location)
where TPixel : struct, IPixel<TPixel>
{
GraphicsOptions options = GraphicsOptions.Default;

14
src/ImageSharp.Drawing/FillRegion.cs

@ -23,7 +23,7 @@ namespace ImageSharp
/// <param name="brush">The details how to fill the region of interest.</param>
/// <param name="options">The graphics options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, GraphicsOptions options)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Apply(new FillProcessor<TPixel>(brush, options));
@ -36,7 +36,7 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="brush">The details how to fill the region of interest.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(brush, GraphicsOptions.Default);
@ -49,7 +49,7 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="color">The color.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, TPixel color)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, TPixel color)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(new SolidBrush<TPixel>(color));
@ -64,7 +64,7 @@ namespace ImageSharp
/// <param name="region">The region.</param>
/// <param name="options">The graphics options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, Region region, GraphicsOptions options)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, Region region, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Apply(new FillRegionProcessor<TPixel>(brush, region, options));
@ -78,7 +78,7 @@ namespace ImageSharp
/// <param name="brush">The brush.</param>
/// <param name="region">The region.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, Region region)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, Region region)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(brush, region, GraphicsOptions.Default);
@ -93,7 +93,7 @@ namespace ImageSharp
/// <param name="region">The region.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, TPixel color, Region region, GraphicsOptions options)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, TPixel color, Region region, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(new SolidBrush<TPixel>(color), region, options);
@ -107,7 +107,7 @@ namespace ImageSharp
/// <param name="color">The color.</param>
/// <param name="region">The region.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, TPixel color, Region region)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, TPixel color, Region region)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(new SolidBrush<TPixel>(color), region);

12
src/ImageSharp.Drawing/Paths/DrawBeziers.cs

@ -28,7 +28,7 @@ namespace ImageSharp
/// <param name="points">The points.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DrawBeziers<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, float thickness, PointF[] points, GraphicsOptions options)
public static IImageOperations<TPixel> DrawBeziers<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, float thickness, PointF[] points, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(new Pen<TPixel>(brush, thickness), new Path(new CubicBezierLineSegment(points)), options);
@ -43,7 +43,7 @@ namespace ImageSharp
/// <param name="thickness">The thickness.</param>
/// <param name="points">The points.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DrawBeziers<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, float thickness, PointF[] points)
public static IImageOperations<TPixel> DrawBeziers<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, float thickness, PointF[] points)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(new Pen<TPixel>(brush, thickness), new Path(new CubicBezierLineSegment(points)));
@ -58,7 +58,7 @@ namespace ImageSharp
/// <param name="thickness">The thickness.</param>
/// <param name="points">The points.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DrawBeziers<TPixel>(this Image<TPixel> source, TPixel color, float thickness, PointF[] points)
public static IImageOperations<TPixel> DrawBeziers<TPixel>(this IImageOperations<TPixel> source, TPixel color, float thickness, PointF[] points)
where TPixel : struct, IPixel<TPixel>
{
return source.DrawBeziers(new SolidBrush<TPixel>(color), thickness, points);
@ -74,7 +74,7 @@ namespace ImageSharp
/// <param name="points">The points.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DrawBeziers<TPixel>(this Image<TPixel> source, TPixel color, float thickness, PointF[] points, GraphicsOptions options)
public static IImageOperations<TPixel> DrawBeziers<TPixel>(this IImageOperations<TPixel> source, TPixel color, float thickness, PointF[] points, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.DrawBeziers(new SolidBrush<TPixel>(color), thickness, points, options);
@ -89,7 +89,7 @@ namespace ImageSharp
/// <param name="points">The points.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DrawBeziers<TPixel>(this Image<TPixel> source, IPen<TPixel> pen, PointF[] points, GraphicsOptions options)
public static IImageOperations<TPixel> DrawBeziers<TPixel>(this IImageOperations<TPixel> source, IPen<TPixel> pen, PointF[] points, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(pen, new Path(new CubicBezierLineSegment(points)), options);
@ -103,7 +103,7 @@ namespace ImageSharp
/// <param name="pen">The pen.</param>
/// <param name="points">The points.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DrawBeziers<TPixel>(this Image<TPixel> source, IPen<TPixel> pen, PointF[] points)
public static IImageOperations<TPixel> DrawBeziers<TPixel>(this IImageOperations<TPixel> source, IPen<TPixel> pen, PointF[] points)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(pen, new Path(new CubicBezierLineSegment(points)));

12
src/ImageSharp.Drawing/Paths/DrawLines.cs

@ -28,7 +28,7 @@ namespace ImageSharp
/// <param name="points">The points.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DrawLines<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, float thickness, PointF[] points, GraphicsOptions options)
public static IImageOperations<TPixel> DrawLines<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, float thickness, PointF[] points, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(new Pen<TPixel>(brush, thickness), new Path(new LinearLineSegment(points)), options);
@ -43,7 +43,7 @@ namespace ImageSharp
/// <param name="thickness">The thickness.</param>
/// <param name="points">The points.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DrawLines<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, float thickness, PointF[] points)
public static IImageOperations<TPixel> DrawLines<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, float thickness, PointF[] points)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(new Pen<TPixel>(brush, thickness), new Path(new LinearLineSegment(points)));
@ -58,7 +58,7 @@ namespace ImageSharp
/// <param name="thickness">The thickness.</param>
/// <param name="points">The points.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DrawLines<TPixel>(this Image<TPixel> source, TPixel color, float thickness, PointF[] points)
public static IImageOperations<TPixel> DrawLines<TPixel>(this IImageOperations<TPixel> source, TPixel color, float thickness, PointF[] points)
where TPixel : struct, IPixel<TPixel>
{
return source.DrawLines(new SolidBrush<TPixel>(color), thickness, points);
@ -74,7 +74,7 @@ namespace ImageSharp
/// <param name="points">The points.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>>
public static Image<TPixel> DrawLines<TPixel>(this Image<TPixel> source, TPixel color, float thickness, PointF[] points, GraphicsOptions options)
public static IImageOperations<TPixel> DrawLines<TPixel>(this IImageOperations<TPixel> source, TPixel color, float thickness, PointF[] points, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.DrawLines(new SolidBrush<TPixel>(color), thickness, points, options);
@ -89,7 +89,7 @@ namespace ImageSharp
/// <param name="points">The points.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DrawLines<TPixel>(this Image<TPixel> source, IPen<TPixel> pen, PointF[] points, GraphicsOptions options)
public static IImageOperations<TPixel> DrawLines<TPixel>(this IImageOperations<TPixel> source, IPen<TPixel> pen, PointF[] points, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(pen, new Path(new LinearLineSegment(points)), options);
@ -103,7 +103,7 @@ namespace ImageSharp
/// <param name="pen">The pen.</param>
/// <param name="points">The points.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DrawLines<TPixel>(this Image<TPixel> source, IPen<TPixel> pen, PointF[] points)
public static IImageOperations<TPixel> DrawLines<TPixel>(this IImageOperations<TPixel> source, IPen<TPixel> pen, PointF[] points)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(pen, new Path(new LinearLineSegment(points)));

12
src/ImageSharp.Drawing/Paths/DrawPath.cs

@ -25,7 +25,7 @@ namespace ImageSharp
/// <param name="path">The path.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Draw<TPixel>(this Image<TPixel> source, IPen<TPixel> pen, IPath path, GraphicsOptions options)
public static IImageOperations<TPixel> Draw<TPixel>(this IImageOperations<TPixel> source, IPen<TPixel> pen, IPath path, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(pen.StrokeFill, new ShapePath(path, pen), options);
@ -39,7 +39,7 @@ namespace ImageSharp
/// <param name="pen">The pen.</param>
/// <param name="path">The path.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Draw<TPixel>(this Image<TPixel> source, IPen<TPixel> pen, IPath path)
public static IImageOperations<TPixel> Draw<TPixel>(this IImageOperations<TPixel> source, IPen<TPixel> pen, IPath path)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(pen, path, GraphicsOptions.Default);
@ -55,7 +55,7 @@ namespace ImageSharp
/// <param name="path">The shape.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Draw<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, float thickness, IPath path, GraphicsOptions options)
public static IImageOperations<TPixel> Draw<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, float thickness, IPath path, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(new Pen<TPixel>(brush, thickness), path, options);
@ -70,7 +70,7 @@ namespace ImageSharp
/// <param name="thickness">The thickness.</param>
/// <param name="path">The path.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Draw<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, float thickness, IPath path)
public static IImageOperations<TPixel> Draw<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, float thickness, IPath path)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(new Pen<TPixel>(brush, thickness), path);
@ -86,7 +86,7 @@ namespace ImageSharp
/// <param name="path">The path.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Draw<TPixel>(this Image<TPixel> source, TPixel color, float thickness, IPath path, GraphicsOptions options)
public static IImageOperations<TPixel> Draw<TPixel>(this IImageOperations<TPixel> source, TPixel color, float thickness, IPath path, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(new SolidBrush<TPixel>(color), thickness, path, options);
@ -101,7 +101,7 @@ namespace ImageSharp
/// <param name="thickness">The thickness.</param>
/// <param name="path">The path.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Draw<TPixel>(this Image<TPixel> source, TPixel color, float thickness, IPath path)
public static IImageOperations<TPixel> Draw<TPixel>(this IImageOperations<TPixel> source, TPixel color, float thickness, IPath path)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(new SolidBrush<TPixel>(color), thickness, path);

12
src/ImageSharp.Drawing/Paths/DrawPathCollection.cs

@ -25,7 +25,7 @@ namespace ImageSharp
/// <param name="paths">The paths.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Draw<TPixel>(this Image<TPixel> source, IPen<TPixel> pen, IPathCollection paths, GraphicsOptions options)
public static IImageOperations<TPixel> Draw<TPixel>(this IImageOperations<TPixel> source, IPen<TPixel> pen, IPathCollection paths, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
foreach (IPath path in paths)
@ -44,7 +44,7 @@ namespace ImageSharp
/// <param name="pen">The pen.</param>
/// <param name="paths">The paths.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Draw<TPixel>(this Image<TPixel> source, IPen<TPixel> pen, IPathCollection paths)
public static IImageOperations<TPixel> Draw<TPixel>(this IImageOperations<TPixel> source, IPen<TPixel> pen, IPathCollection paths)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(pen, paths, GraphicsOptions.Default);
@ -60,7 +60,7 @@ namespace ImageSharp
/// <param name="paths">The shapes.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Draw<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, float thickness, IPathCollection paths, GraphicsOptions options)
public static IImageOperations<TPixel> Draw<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, float thickness, IPathCollection paths, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(new Pen<TPixel>(brush, thickness), paths, options);
@ -75,7 +75,7 @@ namespace ImageSharp
/// <param name="thickness">The thickness.</param>
/// <param name="paths">The paths.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Draw<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, float thickness, IPathCollection paths)
public static IImageOperations<TPixel> Draw<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, float thickness, IPathCollection paths)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(new Pen<TPixel>(brush, thickness), paths);
@ -91,7 +91,7 @@ namespace ImageSharp
/// <param name="paths">The paths.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Draw<TPixel>(this Image<TPixel> source, TPixel color, float thickness, IPathCollection paths, GraphicsOptions options)
public static IImageOperations<TPixel> Draw<TPixel>(this IImageOperations<TPixel> source, TPixel color, float thickness, IPathCollection paths, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(new SolidBrush<TPixel>(color), thickness, paths, options);
@ -106,7 +106,7 @@ namespace ImageSharp
/// <param name="thickness">The thickness.</param>
/// <param name="paths">The paths.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Draw<TPixel>(this Image<TPixel> source, TPixel color, float thickness, IPathCollection paths)
public static IImageOperations<TPixel> Draw<TPixel>(this IImageOperations<TPixel> source, TPixel color, float thickness, IPathCollection paths)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(new SolidBrush<TPixel>(color), thickness, paths);

12
src/ImageSharp.Drawing/Paths/DrawPolygon.cs

@ -28,7 +28,7 @@ namespace ImageSharp
/// <param name="points">The points.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DrawPolygon<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, float thickness, PointF[] points, GraphicsOptions options)
public static IImageOperations<TPixel> DrawPolygon<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, float thickness, PointF[] points, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(new Pen<TPixel>(brush, thickness), new Polygon(new LinearLineSegment(points)), options);
@ -43,7 +43,7 @@ namespace ImageSharp
/// <param name="thickness">The thickness.</param>
/// <param name="points">The points.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DrawPolygon<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, float thickness, PointF[] points)
public static IImageOperations<TPixel> DrawPolygon<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, float thickness, PointF[] points)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(new Pen<TPixel>(brush, thickness), new Polygon(new LinearLineSegment(points)));
@ -58,7 +58,7 @@ namespace ImageSharp
/// <param name="thickness">The thickness.</param>
/// <param name="points">The points.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DrawPolygon<TPixel>(this Image<TPixel> source, TPixel color, float thickness, PointF[] points)
public static IImageOperations<TPixel> DrawPolygon<TPixel>(this IImageOperations<TPixel> source, TPixel color, float thickness, PointF[] points)
where TPixel : struct, IPixel<TPixel>
{
return source.DrawPolygon(new SolidBrush<TPixel>(color), thickness, points);
@ -74,7 +74,7 @@ namespace ImageSharp
/// <param name="points">The points.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DrawPolygon<TPixel>(this Image<TPixel> source, TPixel color, float thickness, PointF[] points, GraphicsOptions options)
public static IImageOperations<TPixel> DrawPolygon<TPixel>(this IImageOperations<TPixel> source, TPixel color, float thickness, PointF[] points, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.DrawPolygon(new SolidBrush<TPixel>(color), thickness, points, options);
@ -88,7 +88,7 @@ namespace ImageSharp
/// <param name="pen">The pen.</param>
/// <param name="points">The points.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DrawPolygon<TPixel>(this Image<TPixel> source, IPen<TPixel> pen, PointF[] points)
public static IImageOperations<TPixel> DrawPolygon<TPixel>(this IImageOperations<TPixel> source, IPen<TPixel> pen, PointF[] points)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(pen, new Polygon(new LinearLineSegment(points)), GraphicsOptions.Default);
@ -103,7 +103,7 @@ namespace ImageSharp
/// <param name="points">The points.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DrawPolygon<TPixel>(this Image<TPixel> source, IPen<TPixel> pen, PointF[] points, GraphicsOptions options)
public static IImageOperations<TPixel> DrawPolygon<TPixel>(this IImageOperations<TPixel> source, IPen<TPixel> pen, PointF[] points, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(pen, new Polygon(new LinearLineSegment(points)), options);

12
src/ImageSharp.Drawing/Paths/DrawRectangle.cs

@ -25,7 +25,7 @@ namespace ImageSharp
/// <param name="shape">The shape.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Draw<TPixel>(this Image<TPixel> source, IPen<TPixel> pen, RectangleF shape, GraphicsOptions options)
public static IImageOperations<TPixel> Draw<TPixel>(this IImageOperations<TPixel> source, IPen<TPixel> pen, RectangleF shape, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(pen, new SixLabors.Shapes.RectangularePolygon(shape.X, shape.Y, shape.Width, shape.Height), options);
@ -39,7 +39,7 @@ namespace ImageSharp
/// <param name="pen">The pen.</param>
/// <param name="shape">The shape.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Draw<TPixel>(this Image<TPixel> source, IPen<TPixel> pen, RectangleF shape)
public static IImageOperations<TPixel> Draw<TPixel>(this IImageOperations<TPixel> source, IPen<TPixel> pen, RectangleF shape)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(pen, shape, GraphicsOptions.Default);
@ -55,7 +55,7 @@ namespace ImageSharp
/// <param name="shape">The shape.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Draw<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, float thickness, RectangleF shape, GraphicsOptions options)
public static IImageOperations<TPixel> Draw<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, float thickness, RectangleF shape, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(new Pen<TPixel>(brush, thickness), shape, options);
@ -70,7 +70,7 @@ namespace ImageSharp
/// <param name="thickness">The thickness.</param>
/// <param name="shape">The shape.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Draw<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, float thickness, RectangleF shape)
public static IImageOperations<TPixel> Draw<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, float thickness, RectangleF shape)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(new Pen<TPixel>(brush, thickness), shape);
@ -86,7 +86,7 @@ namespace ImageSharp
/// <param name="shape">The shape.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Draw<TPixel>(this Image<TPixel> source, TPixel color, float thickness, RectangleF shape, GraphicsOptions options)
public static IImageOperations<TPixel> Draw<TPixel>(this IImageOperations<TPixel> source, TPixel color, float thickness, RectangleF shape, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(new SolidBrush<TPixel>(color), thickness, shape, options);
@ -101,7 +101,7 @@ namespace ImageSharp
/// <param name="thickness">The thickness.</param>
/// <param name="shape">The shape.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Draw<TPixel>(this Image<TPixel> source, TPixel color, float thickness, RectangleF shape)
public static IImageOperations<TPixel> Draw<TPixel>(this IImageOperations<TPixel> source, TPixel color, float thickness, RectangleF shape)
where TPixel : struct, IPixel<TPixel>
{
return source.Draw(new SolidBrush<TPixel>(color), thickness, shape);

8
src/ImageSharp.Drawing/Paths/FillPathBuilder.cs

@ -25,7 +25,7 @@ namespace ImageSharp
/// <param name="path">The shape.</param>
/// <param name="options">The graphics options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, Action<PathBuilder> path, GraphicsOptions options)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, Action<PathBuilder> path, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
var pb = new PathBuilder();
@ -42,7 +42,7 @@ namespace ImageSharp
/// <param name="brush">The brush.</param>
/// <param name="path">The path.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, Action<PathBuilder> path)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, Action<PathBuilder> path)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(brush, path, GraphicsOptions.Default);
@ -57,7 +57,7 @@ namespace ImageSharp
/// <param name="path">The path.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, TPixel color, Action<PathBuilder> path, GraphicsOptions options)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, TPixel color, Action<PathBuilder> path, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(new SolidBrush<TPixel>(color), path, options);
@ -71,7 +71,7 @@ namespace ImageSharp
/// <param name="color">The color.</param>
/// <param name="path">The path.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, TPixel color, Action<PathBuilder> path)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, TPixel color, Action<PathBuilder> path)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(new SolidBrush<TPixel>(color), path);

8
src/ImageSharp.Drawing/Paths/FillPathCollection.cs

@ -24,7 +24,7 @@ namespace ImageSharp
/// <param name="paths">The shapes.</param>
/// <param name="options">The graphics options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, IPathCollection paths, GraphicsOptions options)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, IPathCollection paths, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
foreach (IPath s in paths)
@ -43,7 +43,7 @@ namespace ImageSharp
/// <param name="brush">The brush.</param>
/// <param name="paths">The paths.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, IPathCollection paths)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, IPathCollection paths)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(brush, paths, GraphicsOptions.Default);
@ -58,7 +58,7 @@ namespace ImageSharp
/// <param name="paths">The paths.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, TPixel color, IPathCollection paths, GraphicsOptions options)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, TPixel color, IPathCollection paths, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(new SolidBrush<TPixel>(color), paths, options);
@ -72,7 +72,7 @@ namespace ImageSharp
/// <param name="color">The color.</param>
/// <param name="paths">The paths.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, TPixel color, IPathCollection paths)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, TPixel color, IPathCollection paths)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(new SolidBrush<TPixel>(color), paths);

8
src/ImageSharp.Drawing/Paths/FillPaths.cs

@ -24,7 +24,7 @@ namespace ImageSharp
/// <param name="path">The shape.</param>
/// <param name="options">The graphics options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, IPath path, GraphicsOptions options)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, IPath path, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(brush, new ShapeRegion(path), options);
@ -38,7 +38,7 @@ namespace ImageSharp
/// <param name="brush">The brush.</param>
/// <param name="path">The path.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, IPath path)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, IPath path)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(brush, new ShapeRegion(path), GraphicsOptions.Default);
@ -53,7 +53,7 @@ namespace ImageSharp
/// <param name="path">The path.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, TPixel color, IPath path, GraphicsOptions options)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, TPixel color, IPath path, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(new SolidBrush<TPixel>(color), path, options);
@ -67,7 +67,7 @@ namespace ImageSharp
/// <param name="color">The color.</param>
/// <param name="path">The path.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, TPixel color, IPath path)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, TPixel color, IPath path)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(new SolidBrush<TPixel>(color), path);

8
src/ImageSharp.Drawing/Paths/FillPolygon.cs

@ -27,7 +27,7 @@ namespace ImageSharp
/// <param name="points">The points.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> FillPolygon<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, PointF[] points, GraphicsOptions options)
public static IImageOperations<TPixel> FillPolygon<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, PointF[] points, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(brush, new Polygon(new LinearLineSegment(points)), options);
@ -41,7 +41,7 @@ namespace ImageSharp
/// <param name="brush">The brush.</param>
/// <param name="points">The points.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> FillPolygon<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, PointF[] points)
public static IImageOperations<TPixel> FillPolygon<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, PointF[] points)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(brush, new Polygon(new LinearLineSegment(points)));
@ -56,7 +56,7 @@ namespace ImageSharp
/// <param name="points">The points.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> FillPolygon<TPixel>(this Image<TPixel> source, TPixel color, PointF[] points, GraphicsOptions options)
public static IImageOperations<TPixel> FillPolygon<TPixel>(this IImageOperations<TPixel> source, TPixel color, PointF[] points, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(new SolidBrush<TPixel>(color), new Polygon(new LinearLineSegment(points)), options);
@ -70,7 +70,7 @@ namespace ImageSharp
/// <param name="color">The color.</param>
/// <param name="points">The points.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> FillPolygon<TPixel>(this Image<TPixel> source, TPixel color, PointF[] points)
public static IImageOperations<TPixel> FillPolygon<TPixel>(this IImageOperations<TPixel> source, TPixel color, PointF[] points)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(new SolidBrush<TPixel>(color), new Polygon(new LinearLineSegment(points)));

8
src/ImageSharp.Drawing/Paths/FillRectangle.cs

@ -24,7 +24,7 @@ namespace ImageSharp
/// <param name="shape">The shape.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, RectangleF shape, GraphicsOptions options)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, RectangleF shape, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(brush, new SixLabors.Shapes.RectangularePolygon(shape.X, shape.Y, shape.Width, shape.Height), options);
@ -38,7 +38,7 @@ namespace ImageSharp
/// <param name="brush">The brush.</param>
/// <param name="shape">The shape.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, IBrush<TPixel> brush, RectangleF shape)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, IBrush<TPixel> brush, RectangleF shape)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(brush, new SixLabors.Shapes.RectangularePolygon(shape.X, shape.Y, shape.Width, shape.Height));
@ -53,7 +53,7 @@ namespace ImageSharp
/// <param name="shape">The shape.</param>
/// <param name="options">The options.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, TPixel color, RectangleF shape, GraphicsOptions options)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, TPixel color, RectangleF shape, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(new SolidBrush<TPixel>(color), shape, options);
@ -67,7 +67,7 @@ namespace ImageSharp
/// <param name="color">The color.</param>
/// <param name="shape">The shape.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Fill<TPixel>(this Image<TPixel> source, TPixel color, RectangleF shape)
public static IImageOperations<TPixel> Fill<TPixel>(this IImageOperations<TPixel> source, TPixel color, RectangleF shape)
where TPixel : struct, IPixel<TPixel>
{
return source.Fill(new SolidBrush<TPixel>(color), shape);

2
src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs

@ -70,7 +70,7 @@ namespace ImageSharp.Drawing.Processors
{
if (targetImage.Bounds.Size != this.Size)
{
targetImage = disposableImage = new Image<TPixel>(this.Image).Resize(this.Size.Width, this.Size.Height);
targetImage = disposableImage = this.Image.Generate(x => x.Resize(this.Size.Width, this.Size.Height));
}
// Align start/end positions.

21
src/ImageSharp.Drawing/Text/DrawText.Path.cs

@ -31,7 +31,7 @@ namespace ImageSharp
/// <returns>
/// The <see cref="Image{TPixel}" />.
/// </returns>
public static Image<TPixel> DrawText<TPixel>(this Image<TPixel> source, string text, Font font, TPixel color, IPath path)
public static IImageOperations<TPixel> DrawText<TPixel>(this IImageOperations<TPixel> source, string text, Font font, TPixel color, IPath path)
where TPixel : struct, IPixel<TPixel>
{
return source.DrawText(text, font, color, path, TextGraphicsOptions.Default);
@ -50,7 +50,7 @@ namespace ImageSharp
/// <returns>
/// The <see cref="Image{TPixel}" />.
/// </returns>
public static Image<TPixel> DrawText<TPixel>(this Image<TPixel> source, string text, Font font, TPixel color, IPath path, TextGraphicsOptions options)
public static IImageOperations<TPixel> DrawText<TPixel>(this IImageOperations<TPixel> source, string text, Font font, TPixel color, IPath path, TextGraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.DrawText(text, font, Brushes.Solid(color), null, path, options);
@ -68,7 +68,7 @@ namespace ImageSharp
/// <returns>
/// The <see cref="Image{TPixel}" />.
/// </returns>
public static Image<TPixel> DrawText<TPixel>(this Image<TPixel> source, string text, Font font, IBrush<TPixel> brush, IPath path)
public static IImageOperations<TPixel> DrawText<TPixel>(this IImageOperations<TPixel> source, string text, Font font, IBrush<TPixel> brush, IPath path)
where TPixel : struct, IPixel<TPixel>
{
return source.DrawText(text, font, brush, path, TextGraphicsOptions.Default);
@ -87,7 +87,7 @@ namespace ImageSharp
/// <returns>
/// The <see cref="Image{TPixel}" />.
/// </returns>
public static Image<TPixel> DrawText<TPixel>(this Image<TPixel> source, string text, Font font, IBrush<TPixel> brush, IPath path, TextGraphicsOptions options)
public static IImageOperations<TPixel> DrawText<TPixel>(this IImageOperations<TPixel> source, string text, Font font, IBrush<TPixel> brush, IPath path, TextGraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.DrawText(text, font, brush, null, path, options);
@ -105,7 +105,7 @@ namespace ImageSharp
/// <returns>
/// The <see cref="Image{TPixel}" />.
/// </returns>
public static Image<TPixel> DrawText<TPixel>(this Image<TPixel> source, string text, Font font, IPen<TPixel> pen, IPath path)
public static IImageOperations<TPixel> DrawText<TPixel>(this IImageOperations<TPixel> source, string text, Font font, IPen<TPixel> pen, IPath path)
where TPixel : struct, IPixel<TPixel>
{
return source.DrawText(text, font, pen, path, TextGraphicsOptions.Default);
@ -124,7 +124,7 @@ namespace ImageSharp
/// <returns>
/// The <see cref="Image{TPixel}" />.
/// </returns>
public static Image<TPixel> DrawText<TPixel>(this Image<TPixel> source, string text, Font font, IPen<TPixel> pen, IPath path, TextGraphicsOptions options)
public static IImageOperations<TPixel> DrawText<TPixel>(this IImageOperations<TPixel> source, string text, Font font, IPen<TPixel> pen, IPath path, TextGraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.DrawText(text, font, null, pen, path, options);
@ -143,7 +143,7 @@ namespace ImageSharp
/// <returns>
/// The <see cref="Image{TPixel}" />.
/// </returns>
public static Image<TPixel> DrawText<TPixel>(this Image<TPixel> source, string text, Font font, IBrush<TPixel> brush, IPen<TPixel> pen, IPath path)
public static IImageOperations<TPixel> DrawText<TPixel>(this IImageOperations<TPixel> source, string text, Font font, IBrush<TPixel> brush, IPen<TPixel> pen, IPath path)
where TPixel : struct, IPixel<TPixel>
{
return source.DrawText(text, font, brush, pen, path, TextGraphicsOptions.Default);
@ -163,16 +163,11 @@ namespace ImageSharp
/// <returns>
/// The <see cref="Image{TPixel}" />.
/// </returns>
public static Image<TPixel> DrawText<TPixel>(this Image<TPixel> source, string text, Font font, IBrush<TPixel> brush, IPen<TPixel> pen, IPath path, TextGraphicsOptions options)
public static IImageOperations<TPixel> DrawText<TPixel>(this IImageOperations<TPixel> source, string text, Font font, IBrush<TPixel> brush, IPen<TPixel> pen, IPath path, TextGraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
float dpiX = DefaultTextDpi;
float dpiY = DefaultTextDpi;
if (options.UseImageResolution)
{
dpiX = (float)source.MetaData.HorizontalResolution;
dpiY = (float)source.MetaData.VerticalResolution;
}
var style = new RendererOptions(font, dpiX, dpiY)
{

21
src/ImageSharp.Drawing/Text/DrawText.cs

@ -34,7 +34,7 @@ namespace ImageSharp
/// <returns>
/// The <see cref="Image{TPixel}" />.
/// </returns>
public static Image<TPixel> DrawText<TPixel>(this Image<TPixel> source, string text, Font font, TPixel color, PointF location)
public static IImageOperations<TPixel> DrawText<TPixel>(this IImageOperations<TPixel> source, string text, Font font, TPixel color, PointF location)
where TPixel : struct, IPixel<TPixel>
{
return source.DrawText(text, font, color, location, TextGraphicsOptions.Default);
@ -53,7 +53,7 @@ namespace ImageSharp
/// <returns>
/// The <see cref="Image{TPixel}" />.
/// </returns>
public static Image<TPixel> DrawText<TPixel>(this Image<TPixel> source, string text, Font font, TPixel color, PointF location, TextGraphicsOptions options)
public static IImageOperations<TPixel> DrawText<TPixel>(this IImageOperations<TPixel> source, string text, Font font, TPixel color, PointF location, TextGraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.DrawText(text, font, Brushes.Solid(color), null, location, options);
@ -71,7 +71,7 @@ namespace ImageSharp
/// <returns>
/// The <see cref="Image{TPixel}" />.
/// </returns>
public static Image<TPixel> DrawText<TPixel>(this Image<TPixel> source, string text, Font font, IBrush<TPixel> brush, PointF location)
public static IImageOperations<TPixel> DrawText<TPixel>(this IImageOperations<TPixel> source, string text, Font font, IBrush<TPixel> brush, PointF location)
where TPixel : struct, IPixel<TPixel>
{
return source.DrawText(text, font, brush, location, TextGraphicsOptions.Default);
@ -90,7 +90,7 @@ namespace ImageSharp
/// <returns>
/// The <see cref="Image{TPixel}" />.
/// </returns>
public static Image<TPixel> DrawText<TPixel>(this Image<TPixel> source, string text, Font font, IBrush<TPixel> brush, PointF location, TextGraphicsOptions options)
public static IImageOperations<TPixel> DrawText<TPixel>(this IImageOperations<TPixel> source, string text, Font font, IBrush<TPixel> brush, PointF location, TextGraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.DrawText(text, font, brush, null, location, options);
@ -108,7 +108,7 @@ namespace ImageSharp
/// <returns>
/// The <see cref="Image{TPixel}" />.
/// </returns>
public static Image<TPixel> DrawText<TPixel>(this Image<TPixel> source, string text, Font font, IPen<TPixel> pen, PointF location)
public static IImageOperations<TPixel> DrawText<TPixel>(this IImageOperations<TPixel> source, string text, Font font, IPen<TPixel> pen, PointF location)
where TPixel : struct, IPixel<TPixel>
{
return source.DrawText(text, font, pen, location, TextGraphicsOptions.Default);
@ -127,7 +127,7 @@ namespace ImageSharp
/// <returns>
/// The <see cref="Image{TPixel}" />.
/// </returns>
public static Image<TPixel> DrawText<TPixel>(this Image<TPixel> source, string text, Font font, IPen<TPixel> pen, PointF location, TextGraphicsOptions options)
public static IImageOperations<TPixel> DrawText<TPixel>(this IImageOperations<TPixel> source, string text, Font font, IPen<TPixel> pen, PointF location, TextGraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return source.DrawText(text, font, null, pen, location, options);
@ -146,7 +146,7 @@ namespace ImageSharp
/// <returns>
/// The <see cref="Image{TPixel}" />.
/// </returns>
public static Image<TPixel> DrawText<TPixel>(this Image<TPixel> source, string text, Font font, IBrush<TPixel> brush, IPen<TPixel> pen, PointF location)
public static IImageOperations<TPixel> DrawText<TPixel>(this IImageOperations<TPixel> source, string text, Font font, IBrush<TPixel> brush, IPen<TPixel> pen, PointF location)
where TPixel : struct, IPixel<TPixel>
{
return source.DrawText(text, font, brush, pen, location, TextGraphicsOptions.Default);
@ -166,16 +166,11 @@ namespace ImageSharp
/// <returns>
/// The <see cref="Image{TPixel}" />.
/// </returns>
public static Image<TPixel> DrawText<TPixel>(this Image<TPixel> source, string text, Font font, IBrush<TPixel> brush, IPen<TPixel> pen, PointF location, TextGraphicsOptions options)
public static IImageOperations<TPixel> DrawText<TPixel>(this IImageOperations<TPixel> source, string text, Font font, IBrush<TPixel> brush, IPen<TPixel> pen, PointF location, TextGraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
float dpiX = DefaultTextDpi;
float dpiY = DefaultTextDpi;
if (options.UseImageResolution)
{
dpiX = (float)source.MetaData.HorizontalResolution;
dpiY = (float)source.MetaData.VerticalResolution;
}
var style = new RendererOptions(font, dpiX, dpiY, location)
{

9
src/ImageSharp.Drawing/Text/TextGraphicsOptions.cs

@ -29,8 +29,6 @@ namespace ImageSharp.Drawing
private PixelBlenderMode blenderMode;
private bool? useImageResolution;
private float wrapTextWidth;
private SixLabors.Fonts.HorizontalAlignment? horizontalAlignment;
@ -44,7 +42,6 @@ namespace ImageSharp.Drawing
{
this.applyKerning = true;
this.tabWidth = 4;
this.useImageResolution = false;
this.wrapTextWidth = 0;
this.horizontalAlignment = HorizontalAlignment.Left;
this.verticalAlignment = VerticalAlignment.Top;
@ -89,12 +86,6 @@ namespace ImageSharp.Drawing
/// </summary>
public float TabWidth { get => this.tabWidth ?? 4; set => this.tabWidth = value; }
/// <summary>
/// Gets or sets a value indicating whether to use the current image resultion to for point size scaling.
/// If this is [false] the text renders at 72dpi otherwise it renders at Image resolution
/// </summary>
public bool UseImageResolution { get => this.useImageResolution ?? false; set => this.useImageResolution = value; }
/// <summary>
/// Gets or sets a value indicating if greater than zero determine the width at which text should wrap.
/// </summary>

100
src/ImageSharp/ApplyProcessors.cs

@ -0,0 +1,100 @@
// <copyright file="RotateFlip.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using System;
using ImageSharp.PixelFormats;
using ImageSharp.Processing;
/// <summary>
/// Extension methods for the <see cref="Image{TPixel}"/> type.
/// </summary>
public static partial class ImageExtensions
{
/// <summary>
/// Mutates the image by applying the operations to it.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image to rotate, flip, or both.</param>
/// <param name="operations">The operations to perform on the source.</param>
public static void Mutate<TPixel>(this Image<TPixel> source, Action<IImageOperations<TPixel>> operations)
where TPixel : struct, IPixel<TPixel>
{
Guard.NotNull(operations, nameof(operations));
// TODO: add parameter to Configuration to configure how this is created, create an IImageOperationsFactory that cna be used to switch this out with a fake for testing
var operationsRunner = new ImageOperations<TPixel>(source);
operations(operationsRunner);
}
/// <summary>
/// Mutates the image by applying the operations to it.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image to rotate, flip, or both.</param>
/// <param name="operations">The operations to perform on the source.</param>
public static void Mutate<TPixel>(this Image<TPixel> source, params IImageProcessor<TPixel>[] operations)
where TPixel : struct, IPixel<TPixel>
{
Guard.NotNull(operations, nameof(operations));
// TODO: add parameter to Configuration to configure how this is created, create an IImageOperationsFactory that cna be used to switch this out with a fake for testing
var operationsRunner = new ImageOperations<TPixel>(source);
operationsRunner.ApplyProcessors(operations);
}
/// <summary>
/// Mutates the image by applying the operations to it.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image to rotate, flip, or both.</param>
/// <param name="operations">The operations to perform on the source.</param>
/// <returns>Anew Image which has teh data from the <paramref name="source"/> but with the <paramref name="operations"/> applied.</returns>
public static Image<TPixel> Generate<TPixel>(this Image<TPixel> source, Action<IImageOperations<TPixel>> operations)
where TPixel : struct, IPixel<TPixel>
{
Guard.NotNull(operations, nameof(operations));
var generated = new Image<TPixel>(source);
// TODO: add parameter to Configuration to configure how this is created, create an IImageOperationsFactory that cna be used to switch this out with a fake for testing
var operationsRunner = new ImageOperations<TPixel>(generated);
operations(operationsRunner);
return generated;
}
/// <summary>
/// Mutates the image by applying the operations to it.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image to rotate, flip, or both.</param>
/// <param name="operations">The operations to perform on the source.</param>
/// <returns>Anew Image which has teh data from the <paramref name="source"/> but with the <paramref name="operations"/> applied.</returns>
public static Image<TPixel> Generate<TPixel>(this Image<TPixel> source, params IImageProcessor<TPixel>[] operations)
where TPixel : struct, IPixel<TPixel>
{
Guard.NotNull(operations, nameof(operations));
var generated = new Image<TPixel>(source);
// TODO: add parameter to Configuration to configure how this is created, create an IImageOperationsFactory that cna be used to switch this out with a fake for testing
var operationsRunner = new ImageOperations<TPixel>(generated);
operationsRunner.ApplyProcessors(operations);
return generated;
}
/// <summary>
/// Mutates the image by applying the operations to it.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image to rotate, flip, or both.</param>
/// <param name="operation">The operations to perform on the source.</param>
/// <returns>returns the current optinoatins class to allow chaining of oprations.</returns>
public static IImageOperations<TPixel> Run<TPixel>(this IImageOperations<TPixel> source, Action<Image<TPixel>> operation)
where TPixel : struct, IPixel<TPixel>
=> source.ApplyProcessor(new DelegateImageProcessor<TPixel>(operation));
}
}

19
src/ImageSharp/Formats/Bmp/ImageExtensions.cs

@ -24,11 +24,20 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="stream">The stream to save the image to.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the stream is null.</exception>
/// <returns>
/// The <see cref="Image{TPixel}"/>.
/// </returns>
public static Image<TPixel> SaveAsBmp<TPixel>(this Image<TPixel> source, Stream stream)
public static void SaveAsBmp<TPixel>(this Image<TPixel> source, Stream stream)
where TPixel : struct, IPixel<TPixel>
=> source.Save(stream, new BmpEncoder());
=> source.SaveAsBmp(stream, null);
/// <summary>
/// Saves the image to the given stream with the bmp format.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="stream">The stream to save the image to.</param>
/// <param name="encoder">The encoder to save the image with.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the stream is null.</exception>
public static void SaveAsBmp<TPixel>(this Image<TPixel> source, Stream stream, BmpEncoder encoder)
where TPixel : struct, IPixel<TPixel>
=> source.Save(stream, encoder ?? source.Configuration.FindEncoder(ImageFormats.Bitmap));
}
}

21
src/ImageSharp/Formats/Gif/ImageExtensions.cs

@ -24,14 +24,9 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="stream">The stream to save the image to.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the stream is null.</exception>
/// <returns>
/// The <see cref="Image{TPixel}"/>.
/// </returns>
public static Image<TPixel> SaveAsGif<TPixel>(this Image<TPixel> source, Stream stream)
public static void SaveAsGif<TPixel>(this Image<TPixel> source, Stream stream)
where TPixel : struct, IPixel<TPixel>
{
return SaveAsGif(source, stream, null);
}
=> source.SaveAsGif(stream, null);
/// <summary>
/// Saves the image to the given stream with the gif format.
@ -41,16 +36,8 @@ namespace ImageSharp
/// <param name="stream">The stream to save the image to.</param>
/// <param name="encoder">The options for the encoder.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the stream is null.</exception>
/// <returns>
/// The <see cref="Image{TPixel}"/>.
/// </returns>
public static Image<TPixel> SaveAsGif<TPixel>(this Image<TPixel> source, Stream stream, GifEncoder encoder)
public static void SaveAsGif<TPixel>(this Image<TPixel> source, Stream stream, GifEncoder encoder)
where TPixel : struct, IPixel<TPixel>
{
encoder = encoder ?? new GifEncoder();
encoder.Encode(source, stream);
return source;
}
=> source.Save(stream, encoder ?? source.Configuration.FindEncoder(ImageFormats.Gif));
}
}

21
src/ImageSharp/Formats/Jpeg/ImageExtensions.cs

@ -24,14 +24,9 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="stream">The stream to save the image to.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the stream is null.</exception>
/// <returns>
/// The <see cref="Image{TPixel}"/>.
/// </returns>
public static Image<TPixel> SaveAsJpeg<TPixel>(this Image<TPixel> source, Stream stream)
public static void SaveAsJpeg<TPixel>(this Image<TPixel> source, Stream stream)
where TPixel : struct, IPixel<TPixel>
{
return SaveAsJpeg(source, stream, null);
}
=> SaveAsJpeg(source, stream, null);
/// <summary>
/// Saves the image to the given stream with the jpeg format.
@ -41,16 +36,8 @@ namespace ImageSharp
/// <param name="stream">The stream to save the image to.</param>
/// <param name="encoder">The options for the encoder.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the stream is null.</exception>
/// <returns>
/// The <see cref="Image{TPixel}"/>.
/// </returns>
public static Image<TPixel> SaveAsJpeg<TPixel>(this Image<TPixel> source, Stream stream, JpegEncoder encoder)
public static void SaveAsJpeg<TPixel>(this Image<TPixel> source, Stream stream, JpegEncoder encoder)
where TPixel : struct, IPixel<TPixel>
{
encoder = encoder ?? new JpegEncoder();
encoder.Encode(source, stream);
return source;
}
=> source.Save(stream, encoder ?? source.Configuration.FindEncoder(ImageFormats.Jpeg));
}
}

21
src/ImageSharp/Formats/Png/ImageExtensions.cs

@ -23,14 +23,9 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="stream">The stream to save the image to.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the stream is null.</exception>
/// <returns>
/// The <see cref="Image{TPixel}"/>.
/// </returns>
public static Image<TPixel> SaveAsPng<TPixel>(this Image<TPixel> source, Stream stream)
public static void SaveAsPng<TPixel>(this Image<TPixel> source, Stream stream)
where TPixel : struct, IPixel<TPixel>
{
return SaveAsPng(source, stream, null);
}
=> SaveAsPng(source, stream, null);
/// <summary>
/// Saves the image to the given stream with the png format.
@ -40,16 +35,8 @@ namespace ImageSharp
/// <param name="stream">The stream to save the image to.</param>
/// <param name="encoder">The options for the encoder.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the stream is null.</exception>
/// <returns>
/// The <see cref="Image{TPixel}"/>.
/// </returns>
public static Image<TPixel> SaveAsPng<TPixel>(this Image<TPixel> source, Stream stream, PngEncoder encoder)
public static void SaveAsPng<TPixel>(this Image<TPixel> source, Stream stream, PngEncoder encoder)
where TPixel : struct, IPixel<TPixel>
{
encoder = encoder ?? new PngEncoder();
encoder.Encode(source, stream);
return source;
}
=> source.Save(stream, encoder ?? source.Configuration.FindEncoder(ImageFormats.Png));
}
}

36
src/ImageSharp/IImageOperations{TPixel}.cs

@ -0,0 +1,36 @@
// <copyright file="IImageFormat.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using System;
using ImageSharp.Formats;
using ImageSharp.PixelFormats;
using ImageSharp.Processing;
using SixLabors.Primitives;
/// <summary>
/// The static collection of all the default image formats
/// </summary>
/// <typeparam name="TPixel">The pixel format</typeparam>
public interface IImageOperations<TPixel>
where TPixel : struct, IPixel<TPixel>
{
/// <summary>
/// Adds the processor to the current setr of image operations to be applied.
/// </summary>
/// <param name="processor">The processor to apply</param>
/// <param name="rectangle">The area to apply it to</param>
/// <returns>returns the current optinoatins class to allow chaining of oprations.</returns>
IImageOperations<TPixel> ApplyProcessor(IImageProcessor<TPixel> processor, Rectangle rectangle);
/// <summary>
/// Adds the processor to the current setr of image operations to be applied.
/// </summary>
/// <param name="processor">The processor to apply</param>
/// <returns>returns the current optinoatins class to allow chaining of oprations.</returns>
IImageOperations<TPixel> ApplyProcessor(IImageProcessor<TPixel> processor);
}
}

2
src/ImageSharp/Image/IImageProcessor.cs

@ -42,6 +42,6 @@ namespace ImageSharp.Processing
/// <exception cref="System.ArgumentException">
/// <paramref name="sourceRectangle"/> doesnt fit the dimension of the image.
/// </exception>
void Apply(ImageBase<TPixel> source, Rectangle sourceRectangle);
void Apply(Image<TPixel> source, Rectangle sourceRectangle);
}
}

10
src/ImageSharp/Image/ImageBase{TPixel}.cs

@ -194,16 +194,6 @@ namespace ImageSharp
return this.Pixels.Slice((y * this.Width) + x, this.Width - x);
}
/// <summary>
/// Applies the processor.
/// </summary>
/// <param name="processor">The processor.</param>
/// <param name="rectangle">The rectangle.</param>
public virtual void ApplyProcessor(IImageProcessor<TPixel> processor, Rectangle rectangle)
{
processor.Apply(this, rectangle);
}
/// <inheritdoc />
public void Dispose()
{

4
src/ImageSharp/Image/ImageProcessingExtensions.cs

@ -22,10 +22,10 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="processor">The processor to apply to the image.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Apply<TPixel>(this Image<TPixel> source, IImageProcessor<TPixel> processor)
public static IImageOperations<TPixel> Apply<TPixel>(this IImageOperations<TPixel> source, IImageProcessor<TPixel> processor)
where TPixel : struct, IPixel<TPixel>
{
source.ApplyProcessor(processor, source.Bounds);
source.ApplyProcessor(processor);
return source;
}
}

8
src/ImageSharp/Image/Image{TPixel}.cs

@ -138,14 +138,10 @@ namespace ImageSharp
/// </summary>
/// <param name="processor">The processor to apply to the image.</param>
/// <param name="rectangle">The <see cref="Rectangle" /> structure that specifies the portion of the image object to draw.</param>
public override void ApplyProcessor(IImageProcessor<TPixel> processor, Rectangle rectangle)
public virtual void ApplyProcessor(IImageProcessor<TPixel> processor, Rectangle rectangle)
{
// we want to put this on on here as it gives us a really go place to test/verify processor settings
base.ApplyProcessor(processor, rectangle);
foreach (ImageFrame<TPixel> sourceFrame in this.Frames)
{
sourceFrame.ApplyProcessor(processor, rectangle);
}
processor.Apply(this, rectangle);
}
/// <summary>

62
src/ImageSharp/ImageOperations.cs

@ -0,0 +1,62 @@
// <copyright file="IImageFormat.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using System.Collections.Generic;
using ImageSharp.PixelFormats;
using ImageSharp.Processing;
using SixLabors.Primitives;
/// <summary>
/// The static collection of all the default image formats
/// </summary>
/// <typeparam name="TPixel">The pixel format</typeparam>
internal class ImageOperations<TPixel> : IImageOperations<TPixel>
where TPixel : struct, IPixel<TPixel>
{
private readonly Image<TPixel> image;
/// <summary>
/// Initializes a new instance of the <see cref="ImageOperations{TPixel}"/> class.
/// </summary>
/// <param name="image">The image.</param>
public ImageOperations(Image<TPixel> image)
{
this.image = image;
}
/// <inheritdoc/>
public IImageOperations<TPixel> ApplyProcessor(IImageProcessor<TPixel> processor, Rectangle rectangle)
{
// TODO : make this queue, and allow special processors managage the cloing operation for 'generate'
// to allow things like resize to not need to retain an extra copy of image data in memory, and to
// prevent an pixel copy operation
this.image.ApplyProcessor(processor, rectangle);
return this;
}
/// <inheritdoc/>
public IImageOperations<TPixel> ApplyProcessor(IImageProcessor<TPixel> processor)
{
return this.ApplyProcessor(processor, this.image.Bounds);
}
/// <summary>
/// Applies a bluck colelctino of pressorce at once
/// </summary>
/// <param name="processors">Processors to apply</param>
/// <returns>this </returns>
public IImageOperations<TPixel> ApplyProcessors(IEnumerable<IImageProcessor<TPixel>> processors)
{
foreach (var processor in processors)
{
return this.ApplyProcessor(processor);
}
return this;
}
}
}

124
src/ImageSharp/Numerics/ValueSize.cs

@ -0,0 +1,124 @@
// <copyright file="LongRational.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using SixLabors.Primitives;
/// <summary>
/// Represents a value in relation to a value on the image
/// </summary>
internal struct ValueSize
{
/// <summary>
/// Initializes a new instance of the <see cref="ValueSize"/> struct.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="type">The type.</param>
public ValueSize(float value, ValueSizeType type)
{
if (type != ValueSizeType.Absolute)
{
Guard.MustBeBetweenOrEqualTo(value, 0, 1, nameof(value));
}
this.Value = value;
this.Type = type;
}
/// <summary>
/// The different vlaue types
/// </summary>
public enum ValueSizeType
{
/// <summary>
/// The value is the final return value
/// </summary>
Absolute,
/// <summary>
/// The value is a percentage of the Images Width
/// </summary>
PercentageOfWidth,
/// <summary>
/// The value is a percentage of the Images height
/// </summary>
PercentageOfHeight
}
/// <summary>
/// Gets the value.
/// </summary>
public float Value { get; }
/// <summary>
/// Gets the type.
/// </summary>
public ValueSizeType Type { get; }
/// <summary>
/// Implicitly converts a float into an absolute value
/// </summary>
/// <param name="d">the vlaue to use as the absolute figure.</param>
public static implicit operator ValueSize(float d)
=> Absolute(d);
/// <summary>
/// Create a new ValueSize with as a PercentageOfWidth type with value set to percentage.
/// </summary>
/// <param name="percentage">The percentage.</param>
/// <returns>a Values size with type PercentageOfWidth</returns>
public static ValueSize PercentageOfWidth(float percentage)
{
return new ValueSize(percentage, ValueSizeType.PercentageOfWidth);
}
/// <summary>
/// Create a new ValueSize with as a PercentageOfHeight type with value set to percentage.
/// </summary>
/// <param name="percentage">The percentage.</param>
/// <returns>a Values size with type PercentageOfHeight</returns>
public static ValueSize PercentageOfHeight(float percentage)
{
return new ValueSize(percentage, ValueSizeType.PercentageOfHeight);
}
/// <summary>
/// Create a new ValueSize with as a Absolute type with value set to value.
/// </summary>
/// <param name="value">The value.</param>
/// <returns>a Values size with type Absolute(</returns>
public static ValueSize Absolute(float value)
{
return new ValueSize(value, ValueSizeType.Absolute);
}
/// <summary>
/// Calculates the specified size.
/// </summary>
/// <param name="size">The size.</param>
/// <returns>The calucalted value</returns>
public float Calculate(Size size)
{
switch (this.Type)
{
case ValueSizeType.PercentageOfWidth:
return this.Value * size.Width;
case ValueSizeType.PercentageOfHeight:
return this.Value * size.Height;
case ValueSizeType.Absolute:
default:
return this.Value;
}
}
/// <inheritdoc/>
public override string ToString()
{
return $"{this.Value} - {this.Type}";
}
}
}

7
src/ImageSharp/Processing/Binarization/BinaryThreshold.cs

@ -24,10 +24,11 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="threshold">The threshold to apply binarization of the image. Must be between 0 and 1.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> BinaryThreshold<TPixel>(this Image<TPixel> source, float threshold)
public static IImageOperations<TPixel> BinaryThreshold<TPixel>(this IImageOperations<TPixel> source, float threshold)
where TPixel : struct, IPixel<TPixel>
{
return BinaryThreshold(source, threshold, source.Bounds);
source.ApplyProcessor(new BinaryThresholdProcessor<TPixel>(threshold));
return source;
}
/// <summary>
@ -40,7 +41,7 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> BinaryThreshold<TPixel>(this Image<TPixel> source, float threshold, Rectangle rectangle)
public static IImageOperations<TPixel> BinaryThreshold<TPixel>(this IImageOperations<TPixel> source, float threshold, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
source.ApplyProcessor(new BinaryThresholdProcessor<TPixel>(threshold), rectangle);

14
src/ImageSharp/Processing/Binarization/Dither.cs

@ -25,10 +25,11 @@ namespace ImageSharp
/// <param name="dither">The ordered ditherer.</param>
/// <param name="index">The component index to test the threshold against. Must range from 0 to 3.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Dither<TPixel>(this Image<TPixel> source, IOrderedDither dither, int index = 0)
public static IImageOperations<TPixel> Dither<TPixel>(this IImageOperations<TPixel> source, IOrderedDither dither, int index = 0)
where TPixel : struct, IPixel<TPixel>
{
return Dither(source, dither, source.Bounds, index);
source.ApplyProcessor(new OrderedDitherProcessor<TPixel>(dither, index));
return source;
}
/// <summary>
@ -42,7 +43,7 @@ namespace ImageSharp
/// </param>
/// <param name="index">The component index to test the threshold against. Must range from 0 to 3.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Dither<TPixel>(this Image<TPixel> source, IOrderedDither dither, Rectangle rectangle, int index = 0)
public static IImageOperations<TPixel> Dither<TPixel>(this IImageOperations<TPixel> source, IOrderedDither dither, Rectangle rectangle, int index = 0)
where TPixel : struct, IPixel<TPixel>
{
source.ApplyProcessor(new OrderedDitherProcessor<TPixel>(dither, index), rectangle);
@ -57,10 +58,11 @@ namespace ImageSharp
/// <param name="diffuser">The diffusion algorithm to apply.</param>
/// <param name="threshold">The threshold to apply binarization of the image. Must be between 0 and 1.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Dither<TPixel>(this Image<TPixel> source, IErrorDiffuser diffuser, float threshold)
public static IImageOperations<TPixel> Dither<TPixel>(this IImageOperations<TPixel> source, IErrorDiffuser diffuser, float threshold)
where TPixel : struct, IPixel<TPixel>
{
return Dither(source, diffuser, threshold, source.Bounds);
source.ApplyProcessor(new ErrorDiffusionDitherProcessor<TPixel>(diffuser, threshold));
return source;
}
/// <summary>
@ -74,7 +76,7 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Dither<TPixel>(this Image<TPixel> source, IErrorDiffuser diffuser, float threshold, Rectangle rectangle)
public static IImageOperations<TPixel> Dither<TPixel>(this IImageOperations<TPixel> source, IErrorDiffuser diffuser, float threshold, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
source.ApplyProcessor(new ErrorDiffusionDitherProcessor<TPixel>(diffuser, threshold), rectangle);

7
src/ImageSharp/Processing/ColorMatrix/BlackWhite.cs

@ -24,10 +24,11 @@ namespace ImageSharp
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> BlackWhite<TPixel>(this Image<TPixel> source)
public static IImageOperations<TPixel> BlackWhite<TPixel>(this IImageOperations<TPixel> source)
where TPixel : struct, IPixel<TPixel>
{
return BlackWhite(source, source.Bounds);
source.ApplyProcessor(new BlackWhiteProcessor<TPixel>());
return source;
}
/// <summary>
@ -39,7 +40,7 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> BlackWhite<TPixel>(this Image<TPixel> source, Rectangle rectangle)
public static IImageOperations<TPixel> BlackWhite<TPixel>(this IImageOperations<TPixel> source, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
source.ApplyProcessor(new BlackWhiteProcessor<TPixel>(), rectangle);

48
src/ImageSharp/Processing/ColorMatrix/ColorBlindness.cs

@ -25,10 +25,11 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="colorBlindness">The type of color blindness simulator to apply.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> ColorBlindness<TPixel>(this Image<TPixel> source, ColorBlindness colorBlindness)
public static IImageOperations<TPixel> ColorBlindness<TPixel>(this IImageOperations<TPixel> source, ColorBlindness colorBlindness)
where TPixel : struct, IPixel<TPixel>
{
return ColorBlindness(source, colorBlindness, source.Bounds);
source.ApplyProcessor(GetProcessor<TPixel>(colorBlindness));
return source;
}
/// <summary>
@ -41,48 +42,35 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> ColorBlindness<TPixel>(this Image<TPixel> source, ColorBlindness colorBlindness, Rectangle rectangle)
public static IImageOperations<TPixel> ColorBlindness<TPixel>(this IImageOperations<TPixel> source, ColorBlindness colorBlindness, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
IImageProcessor<TPixel> processor;
source.ApplyProcessor(GetProcessor<TPixel>(colorBlindness), rectangle);
return source;
}
private static IImageProcessor<TPixel> GetProcessor<TPixel>(ColorBlindness colorBlindness)
where TPixel : struct, IPixel<TPixel>
{
switch (colorBlindness)
{
case ImageSharp.Processing.ColorBlindness.Achromatomaly:
processor = new AchromatomalyProcessor<TPixel>();
break;
return new AchromatomalyProcessor<TPixel>();
case ImageSharp.Processing.ColorBlindness.Achromatopsia:
processor = new AchromatopsiaProcessor<TPixel>();
break;
return new AchromatopsiaProcessor<TPixel>();
case ImageSharp.Processing.ColorBlindness.Deuteranomaly:
processor = new DeuteranomalyProcessor<TPixel>();
break;
return new DeuteranomalyProcessor<TPixel>();
case ImageSharp.Processing.ColorBlindness.Deuteranopia:
processor = new DeuteranopiaProcessor<TPixel>();
break;
return new DeuteranopiaProcessor<TPixel>();
case ImageSharp.Processing.ColorBlindness.Protanomaly:
processor = new ProtanomalyProcessor<TPixel>();
break;
return new ProtanomalyProcessor<TPixel>();
case ImageSharp.Processing.ColorBlindness.Protanopia:
processor = new ProtanopiaProcessor<TPixel>();
break;
return new ProtanopiaProcessor<TPixel>();
case ImageSharp.Processing.ColorBlindness.Tritanomaly:
processor = new TritanomalyProcessor<TPixel>();
break;
return new TritanomalyProcessor<TPixel>();
default:
processor = new TritanopiaProcessor<TPixel>();
break;
return new TritanopiaProcessor<TPixel>();
}
source.ApplyProcessor(processor, rectangle);
return source;
}
}
}

20
src/ImageSharp/Processing/ColorMatrix/Grayscale.cs

@ -22,7 +22,7 @@ namespace ImageSharp
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Grayscale<TPixel>(this Image<TPixel> source)
public static IImageOperations<TPixel> Grayscale<TPixel>(this IImageOperations<TPixel> source)
where TPixel : struct, IPixel<TPixel>
{
return Grayscale(source, GrayscaleMode.Bt709);
@ -35,10 +35,15 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="mode">The formula to apply to perform the operation.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Grayscale<TPixel>(this Image<TPixel> source, GrayscaleMode mode)
public static IImageOperations<TPixel> Grayscale<TPixel>(this IImageOperations<TPixel> source, GrayscaleMode mode)
where TPixel : struct, IPixel<TPixel>
{
return Grayscale(source, mode, source.Bounds);
IImageProcessor<TPixel> processor = mode == GrayscaleMode.Bt709
? (IImageProcessor<TPixel>)new GrayscaleBt709Processor<TPixel>()
: new GrayscaleBt601Processor<TPixel>();
source.ApplyProcessor(processor);
return source;
}
/// <summary>
@ -50,13 +55,10 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Grayscale<TPixel>(this Image<TPixel> source, Rectangle rectangle)
public static IImageOperations<TPixel> Grayscale<TPixel>(this IImageOperations<TPixel> source, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
IImageProcessor<TPixel> processor = new GrayscaleBt709Processor<TPixel>();
source.ApplyProcessor(processor, rectangle);
return source;
return Grayscale(source, GrayscaleMode.Bt709, rectangle);
}
/// <summary>
@ -69,7 +71,7 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Grayscale<TPixel>(this Image<TPixel> source, GrayscaleMode mode, Rectangle rectangle)
public static IImageOperations<TPixel> Grayscale<TPixel>(this IImageOperations<TPixel> source, GrayscaleMode mode, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
IImageProcessor<TPixel> processor = mode == GrayscaleMode.Bt709

7
src/ImageSharp/Processing/ColorMatrix/Hue.cs

@ -25,10 +25,11 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="degrees">The angle in degrees to adjust the image.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Hue<TPixel>(this Image<TPixel> source, float degrees)
public static IImageOperations<TPixel> Hue<TPixel>(this IImageOperations<TPixel> source, float degrees)
where TPixel : struct, IPixel<TPixel>
{
return Hue(source, degrees, source.Bounds);
source.ApplyProcessor(new HueProcessor<TPixel>(degrees));
return source;
}
/// <summary>
@ -41,7 +42,7 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Hue<TPixel>(this Image<TPixel> source, float degrees, Rectangle rectangle)
public static IImageOperations<TPixel> Hue<TPixel>(this IImageOperations<TPixel> source, float degrees, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
source.ApplyProcessor(new HueProcessor<TPixel>(degrees), rectangle);

7
src/ImageSharp/Processing/ColorMatrix/Kodachrome.cs

@ -24,10 +24,11 @@ namespace ImageSharp
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Kodachrome<TPixel>(this Image<TPixel> source)
public static IImageOperations<TPixel> Kodachrome<TPixel>(this IImageOperations<TPixel> source)
where TPixel : struct, IPixel<TPixel>
{
return Kodachrome(source, source.Bounds);
source.ApplyProcessor(new KodachromeProcessor<TPixel>());
return source;
}
/// <summary>
@ -39,7 +40,7 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Kodachrome<TPixel>(this Image<TPixel> source, Rectangle rectangle)
public static IImageOperations<TPixel> Kodachrome<TPixel>(this IImageOperations<TPixel> source, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
source.ApplyProcessor(new KodachromeProcessor<TPixel>(), rectangle);

13
src/ImageSharp/Processing/ColorMatrix/Lomograph.cs

@ -24,10 +24,10 @@ namespace ImageSharp
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Lomograph<TPixel>(this Image<TPixel> source)
public static IImageOperations<TPixel> Lomograph<TPixel>(this IImageOperations<TPixel> source)
where TPixel : struct, IPixel<TPixel>
{
return Lomograph(source, source.Bounds, GraphicsOptions.Default);
return Lomograph(source, GraphicsOptions.Default);
}
/// <summary>
@ -39,7 +39,7 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Lomograph<TPixel>(this Image<TPixel> source, Rectangle rectangle)
public static IImageOperations<TPixel> Lomograph<TPixel>(this IImageOperations<TPixel> source, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
return Lomograph(source, rectangle, GraphicsOptions.Default);
@ -52,10 +52,11 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="options">The options effecting pixel blending.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Lomograph<TPixel>(this Image<TPixel> source, GraphicsOptions options)
public static IImageOperations<TPixel> Lomograph<TPixel>(this IImageOperations<TPixel> source, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return Lomograph(source, source.Bounds, options);
source.ApplyProcessor(new LomographProcessor<TPixel>(options));
return source;
}
/// <summary>
@ -68,7 +69,7 @@ namespace ImageSharp
/// </param>
/// <param name="options">The options effecting pixel blending.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Lomograph<TPixel>(this Image<TPixel> source, Rectangle rectangle, GraphicsOptions options)
public static IImageOperations<TPixel> Lomograph<TPixel>(this IImageOperations<TPixel> source, Rectangle rectangle, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
source.ApplyProcessor(new LomographProcessor<TPixel>(options), rectangle);

11
src/ImageSharp/Processing/ColorMatrix/Polaroid.cs

@ -24,7 +24,7 @@ namespace ImageSharp
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Polaroid<TPixel>(this Image<TPixel> source)
public static IImageOperations<TPixel> Polaroid<TPixel>(this IImageOperations<TPixel> source)
where TPixel : struct, IPixel<TPixel>
{
return Polaroid(source, GraphicsOptions.Default);
@ -39,7 +39,7 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Polaroid<TPixel>(this Image<TPixel> source, Rectangle rectangle)
public static IImageOperations<TPixel> Polaroid<TPixel>(this IImageOperations<TPixel> source, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
return Polaroid(source, rectangle, GraphicsOptions.Default);
@ -52,10 +52,11 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="options">The options effecting pixel blending.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Polaroid<TPixel>(this Image<TPixel> source, GraphicsOptions options)
public static IImageOperations<TPixel> Polaroid<TPixel>(this IImageOperations<TPixel> source, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return Polaroid(source, source.Bounds, options);
source.ApplyProcessor(new PolaroidProcessor<TPixel>(options));
return source;
}
/// <summary>
@ -68,7 +69,7 @@ namespace ImageSharp
/// </param>
/// <param name="options">The options effecting pixel blending.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Polaroid<TPixel>(this Image<TPixel> source, Rectangle rectangle, GraphicsOptions options)
public static IImageOperations<TPixel> Polaroid<TPixel>(this IImageOperations<TPixel> source, Rectangle rectangle, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
source.ApplyProcessor(new PolaroidProcessor<TPixel>(options), rectangle);

7
src/ImageSharp/Processing/ColorMatrix/Saturation.cs

@ -25,10 +25,11 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="amount">The new saturation of the image. Must be between -100 and 100.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Saturation<TPixel>(this Image<TPixel> source, int amount)
public static IImageOperations<TPixel> Saturation<TPixel>(this IImageOperations<TPixel> source, int amount)
where TPixel : struct, IPixel<TPixel>
{
return Saturation(source, amount, source.Bounds);
source.ApplyProcessor(new SaturationProcessor<TPixel>(amount));
return source;
}
/// <summary>
@ -41,7 +42,7 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Saturation<TPixel>(this Image<TPixel> source, int amount, Rectangle rectangle)
public static IImageOperations<TPixel> Saturation<TPixel>(this IImageOperations<TPixel> source, int amount, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
source.ApplyProcessor(new SaturationProcessor<TPixel>(amount), rectangle);

13
src/ImageSharp/Processing/ColorMatrix/Sepia.cs

@ -24,11 +24,9 @@ namespace ImageSharp
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Sepia<TPixel>(this Image<TPixel> source)
public static IImageOperations<TPixel> Sepia<TPixel>(this IImageOperations<TPixel> source)
where TPixel : struct, IPixel<TPixel>
{
return Sepia(source, source.Bounds);
}
=> source.ApplyProcessor(new SepiaProcessor<TPixel>());
/// <summary>
/// Applies sepia toning to the image.
@ -39,11 +37,8 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Sepia<TPixel>(this Image<TPixel> source, Rectangle rectangle)
public static IImageOperations<TPixel> Sepia<TPixel>(this IImageOperations<TPixel> source, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
source.ApplyProcessor(new SepiaProcessor<TPixel>(), rectangle);
return source;
}
=> source.ApplyProcessor(new SepiaProcessor<TPixel>(), rectangle);
}
}

13
src/ImageSharp/Processing/Convolution/BoxBlur.cs

@ -24,11 +24,9 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="radius">The 'radius' value representing the size of the area to sample.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> BoxBlur<TPixel>(this Image<TPixel> source, int radius = 7)
public static IImageOperations<TPixel> BoxBlur<TPixel>(this IImageOperations<TPixel> source, int radius = 7)
where TPixel : struct, IPixel<TPixel>
{
return BoxBlur(source, radius, source.Bounds);
}
=> source.ApplyProcessor(new BoxBlurProcessor<TPixel>(radius));
/// <summary>
/// Applies a box blur to the image.
@ -40,11 +38,8 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> BoxBlur<TPixel>(this Image<TPixel> source, int radius, Rectangle rectangle)
public static IImageOperations<TPixel> BoxBlur<TPixel>(this IImageOperations<TPixel> source, int radius, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
source.ApplyProcessor(new BoxBlurProcessor<TPixel>(radius), rectangle);
return source;
}
=> source.ApplyProcessor(new BoxBlurProcessor<TPixel>(radius), rectangle);
}
}

80
src/ImageSharp/Processing/Convolution/DetectEdges.cs

@ -25,10 +25,10 @@ namespace ImageSharp
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DetectEdges<TPixel>(this Image<TPixel> source)
public static IImageOperations<TPixel> DetectEdges<TPixel>(this IImageOperations<TPixel> source)
where TPixel : struct, IPixel<TPixel>
{
return DetectEdges(source, source.Bounds, new SobelProcessor<TPixel> { Grayscale = true });
return DetectEdges(source, new SobelProcessor<TPixel> { Grayscale = true });
}
/// <summary>
@ -41,7 +41,7 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DetectEdges<TPixel>(this Image<TPixel> source, Rectangle rectangle)
public static IImageOperations<TPixel> DetectEdges<TPixel>(this IImageOperations<TPixel> source, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
return DetectEdges(source, rectangle, new SobelProcessor<TPixel> { Grayscale = true });
@ -55,11 +55,9 @@ namespace ImageSharp
/// <param name="filter">The filter for detecting edges.</param>
/// <param name="grayscale">Whether to convert the image to Grayscale first. Defaults to true.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DetectEdges<TPixel>(this Image<TPixel> source, EdgeDetection filter, bool grayscale = true)
public static IImageOperations<TPixel> DetectEdges<TPixel>(this IImageOperations<TPixel> source, EdgeDetection filter, bool grayscale = true)
where TPixel : struct, IPixel<TPixel>
{
return DetectEdges(source, filter, source.Bounds, grayscale);
}
=> DetectEdges(source, GetProcessor<TPixel>(filter, grayscale));
/// <summary>
/// Detects any edges within the image.
@ -72,7 +70,41 @@ namespace ImageSharp
/// </param>
/// <param name="grayscale">Whether to convert the image to Grayscale first. Defaults to true.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DetectEdges<TPixel>(this Image<TPixel> source, EdgeDetection filter, Rectangle rectangle, bool grayscale = true)
public static IImageOperations<TPixel> DetectEdges<TPixel>(this IImageOperations<TPixel> source, EdgeDetection filter, Rectangle rectangle, bool grayscale = true)
where TPixel : struct, IPixel<TPixel>
=> DetectEdges(source, rectangle, GetProcessor<TPixel>(filter, grayscale));
/// <summary>
/// Detects any edges within the image.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="filter">The filter for detecting edges.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static IImageOperations<TPixel> DetectEdges<TPixel>(this IImageOperations<TPixel> source, IEdgeDetectorProcessor<TPixel> filter)
where TPixel : struct, IPixel<TPixel>
{
return source.ApplyProcessor(filter);
}
/// <summary>
/// Detects any edges within the image.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <param name="filter">The filter for detecting edges.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static IImageOperations<TPixel> DetectEdges<TPixel>(this IImageOperations<TPixel> source, Rectangle rectangle, IEdgeDetectorProcessor<TPixel> filter)
where TPixel : struct, IPixel<TPixel>
{
source.ApplyProcessor(filter, rectangle);
return source;
}
private static IEdgeDetectorProcessor<TPixel> GetProcessor<TPixel>(EdgeDetection filter, bool grayscale)
where TPixel : struct, IPixel<TPixel>
{
IEdgeDetectorProcessor<TPixel> processor;
@ -120,37 +152,7 @@ namespace ImageSharp
break;
}
return DetectEdges(source, rectangle, processor);
}
/// <summary>
/// Detects any edges within the image.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="filter">The filter for detecting edges.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DetectEdges<TPixel>(this Image<TPixel> source, IEdgeDetectorProcessor<TPixel> filter)
where TPixel : struct, IPixel<TPixel>
{
return DetectEdges(source, source.Bounds, filter);
}
/// <summary>
/// Detects any edges within the image.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <param name="filter">The filter for detecting edges.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> DetectEdges<TPixel>(this Image<TPixel> source, Rectangle rectangle, IEdgeDetectorProcessor<TPixel> filter)
where TPixel : struct, IPixel<TPixel>
{
source.ApplyProcessor(filter, rectangle);
return source;
return processor;
}
}
}

13
src/ImageSharp/Processing/Convolution/GaussianBlur.cs

@ -25,11 +25,9 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="sigma">The 'sigma' value representing the weight of the blur.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> GaussianBlur<TPixel>(this Image<TPixel> source, float sigma = 3f)
public static IImageOperations<TPixel> GaussianBlur<TPixel>(this IImageOperations<TPixel> source, float sigma = 3f)
where TPixel : struct, IPixel<TPixel>
{
return GaussianBlur(source, sigma, source.Bounds);
}
=> source.ApplyProcessor(new GaussianBlurProcessor<TPixel>(sigma));
/// <summary>
/// Applies a Gaussian blur to the image.
@ -41,11 +39,8 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> GaussianBlur<TPixel>(this Image<TPixel> source, float sigma, Rectangle rectangle)
public static IImageOperations<TPixel> GaussianBlur<TPixel>(this IImageOperations<TPixel> source, float sigma, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
source.ApplyProcessor(new GaussianBlurProcessor<TPixel>(sigma), rectangle);
return source;
}
=> source.ApplyProcessor(new GaussianBlurProcessor<TPixel>(sigma), rectangle);
}
}

13
src/ImageSharp/Processing/Convolution/GaussianSharpen.cs

@ -25,11 +25,9 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="sigma">The 'sigma' value representing the weight of the blur.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> GaussianSharpen<TPixel>(this Image<TPixel> source, float sigma = 3f)
public static IImageOperations<TPixel> GaussianSharpen<TPixel>(this IImageOperations<TPixel> source, float sigma = 3f)
where TPixel : struct, IPixel<TPixel>
{
return GaussianSharpen(source, sigma, source.Bounds);
}
=> source.ApplyProcessor(new GaussianSharpenProcessor<TPixel>(sigma));
/// <summary>
/// Applies a Gaussian sharpening filter to the image.
@ -41,11 +39,8 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> GaussianSharpen<TPixel>(this Image<TPixel> source, float sigma, Rectangle rectangle)
public static IImageOperations<TPixel> GaussianSharpen<TPixel>(this IImageOperations<TPixel> source, float sigma, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
source.ApplyProcessor(new GaussianSharpenProcessor<TPixel>(sigma), rectangle);
return source;
}
=> source.ApplyProcessor(new GaussianSharpenProcessor<TPixel>(sigma), rectangle);
}
}

44
src/ImageSharp/Processing/DelegateImageProcessor.cs

@ -0,0 +1,44 @@
// <copyright file="DelegateImageProcessor.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Processing
{
using System;
using System.Threading.Tasks;
using ImageSharp.PixelFormats;
using SixLabors.Primitives;
/// <summary>
/// Allows the application of processors to images.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
internal class DelegateImageProcessor<TPixel> : ImageProcessor<TPixel>
where TPixel : struct, IPixel<TPixel>
{
private readonly Action<Image<TPixel>> action;
/// <summary>
/// Initializes a new instance of the <see cref="DelegateImageProcessor{TPixel}"/> class.
/// </summary>
/// <param name="action">The action.</param>
public DelegateImageProcessor(Action<Image<TPixel>> action)
{
this.action = action;
}
/// <inheritdoc/>
protected override void BeforeImageApply(Image<TPixel> source, Rectangle sourceRectangle)
{
this.action?.Invoke((Image<TPixel>)source);
}
/// <inheritdoc/>
protected override void OnApply(ImageBase<TPixel> source, Rectangle sourceRectangle)
{
// no op, we did all we wanted to do inside BeforeImageApply
}
}
}

13
src/ImageSharp/Processing/Effects/Alpha.cs

@ -24,11 +24,9 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="percent">The new opacity of the image. Must be between 0 and 1.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Alpha<TPixel>(this Image<TPixel> source, float percent)
public static IImageOperations<TPixel> Alpha<TPixel>(this IImageOperations<TPixel> source, float percent)
where TPixel : struct, IPixel<TPixel>
{
return Alpha(source, percent, source.Bounds);
}
=> source.ApplyProcessor(new AlphaProcessor<TPixel>(percent));
/// <summary>
/// Alters the alpha component of the image.
@ -40,11 +38,8 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Alpha<TPixel>(this Image<TPixel> source, float percent, Rectangle rectangle)
public static IImageOperations<TPixel> Alpha<TPixel>(this IImageOperations<TPixel> source, float percent, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
source.ApplyProcessor(new AlphaProcessor<TPixel>(percent), rectangle);
return source;
}
=> source.ApplyProcessor(new AlphaProcessor<TPixel>(percent), rectangle);
}
}

17
src/ImageSharp/Processing/Effects/BackgroundColor.cs

@ -25,11 +25,9 @@ namespace ImageSharp
/// <param name="color">The color to set as the background.</param>
/// <param name="options">The options effecting pixel blending.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> BackgroundColor<TPixel>(this Image<TPixel> source, TPixel color, GraphicsOptions options)
public static IImageOperations<TPixel> BackgroundColor<TPixel>(this IImageOperations<TPixel> source, TPixel color, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return BackgroundColor(source, color, source.Bounds, options);
}
=> source.ApplyProcessor(new BackgroundColorProcessor<TPixel>(color, options));
/// <summary>
/// Replaces the background color of image with the given one.
@ -42,12 +40,9 @@ namespace ImageSharp
/// </param>
/// <param name="options">The options effecting pixel blending.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> BackgroundColor<TPixel>(this Image<TPixel> source, TPixel color, Rectangle rectangle, GraphicsOptions options)
public static IImageOperations<TPixel> BackgroundColor<TPixel>(this IImageOperations<TPixel> source, TPixel color, Rectangle rectangle, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
source.ApplyProcessor(new BackgroundColorProcessor<TPixel>(color, options), rectangle);
return source;
}
=> source.ApplyProcessor(new BackgroundColorProcessor<TPixel>(color, options), rectangle);
/// <summary>
/// Replaces the background color of image with the given one.
@ -56,7 +51,7 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="color">The color to set as the background.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> BackgroundColor<TPixel>(this Image<TPixel> source, TPixel color)
public static IImageOperations<TPixel> BackgroundColor<TPixel>(this IImageOperations<TPixel> source, TPixel color)
where TPixel : struct, IPixel<TPixel>
{
return BackgroundColor(source, color, GraphicsOptions.Default);
@ -72,7 +67,7 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> BackgroundColor<TPixel>(this Image<TPixel> source, TPixel color, Rectangle rectangle)
public static IImageOperations<TPixel> BackgroundColor<TPixel>(this IImageOperations<TPixel> source, TPixel color, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
return BackgroundColor(source, color, rectangle, GraphicsOptions.Default);

13
src/ImageSharp/Processing/Effects/Brightness.cs

@ -24,11 +24,9 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="amount">The new brightness of the image. Must be between -100 and 100.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Brightness<TPixel>(this Image<TPixel> source, int amount)
public static IImageOperations<TPixel> Brightness<TPixel>(this IImageOperations<TPixel> source, int amount)
where TPixel : struct, IPixel<TPixel>
{
return Brightness(source, amount, source.Bounds);
}
=> source.ApplyProcessor(new BrightnessProcessor<TPixel>(amount));
/// <summary>
/// Alters the brightness component of the image.
@ -40,11 +38,8 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Brightness<TPixel>(this Image<TPixel> source, int amount, Rectangle rectangle)
public static IImageOperations<TPixel> Brightness<TPixel>(this IImageOperations<TPixel> source, int amount, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
source.ApplyProcessor(new BrightnessProcessor<TPixel>(amount), rectangle);
return source;
}
=> source.ApplyProcessor(new BrightnessProcessor<TPixel>(amount), rectangle);
}
}

13
src/ImageSharp/Processing/Effects/Contrast.cs

@ -24,11 +24,9 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="amount">The new contrast of the image. Must be between -100 and 100.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Contrast<TPixel>(this Image<TPixel> source, int amount)
public static IImageOperations<TPixel> Contrast<TPixel>(this IImageOperations<TPixel> source, int amount)
where TPixel : struct, IPixel<TPixel>
{
return Contrast(source, amount, source.Bounds);
}
=> source.ApplyProcessor(new ContrastProcessor<TPixel>(amount));
/// <summary>
/// Alters the contrast component of the image.
@ -40,11 +38,8 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Contrast<TPixel>(this Image<TPixel> source, int amount, Rectangle rectangle)
public static IImageOperations<TPixel> Contrast<TPixel>(this IImageOperations<TPixel> source, int amount, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
source.ApplyProcessor(new ContrastProcessor<TPixel>(amount), rectangle);
return source;
}
=> source.ApplyProcessor(new ContrastProcessor<TPixel>(amount), rectangle);
}
}

13
src/ImageSharp/Processing/Effects/Invert.cs

@ -23,11 +23,9 @@ namespace ImageSharp
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Invert<TPixel>(this Image<TPixel> source)
public static IImageOperations<TPixel> Invert<TPixel>(this IImageOperations<TPixel> source)
where TPixel : struct, IPixel<TPixel>
{
return Invert(source, source.Bounds);
}
=> source.ApplyProcessor(new InvertProcessor<TPixel>());
/// <summary>
/// Inverts the colors of the image.
@ -38,11 +36,8 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Invert<TPixel>(this Image<TPixel> source, Rectangle rectangle)
public static IImageOperations<TPixel> Invert<TPixel>(this IImageOperations<TPixel> source, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
source.ApplyProcessor(new InvertProcessor<TPixel>(), rectangle);
return source;
}
=> source.ApplyProcessor(new InvertProcessor<TPixel>(), rectangle);
}
}

26
src/ImageSharp/Processing/Effects/OilPainting.cs

@ -24,7 +24,7 @@ namespace ImageSharp
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> OilPaint<TPixel>(this Image<TPixel> source)
public static IImageOperations<TPixel> OilPaint<TPixel>(this IImageOperations<TPixel> source)
where TPixel : struct, IPixel<TPixel>
{
return OilPaint(source, 10, 15);
@ -40,7 +40,7 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> OilPaint<TPixel>(this Image<TPixel> source, Rectangle rectangle)
public static IImageOperations<TPixel> OilPaint<TPixel>(this IImageOperations<TPixel> source, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
return OilPaint(source, 10, 15, rectangle);
@ -54,11 +54,9 @@ namespace ImageSharp
/// <param name="levels">The number of intensity levels. Higher values result in a broader range of color intensities forming part of the result image.</param>
/// <param name="brushSize">The number of neighboring pixels used in calculating each individual pixel value.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> OilPaint<TPixel>(this Image<TPixel> source, int levels, int brushSize)
where TPixel : struct, IPixel<TPixel>
{
return OilPaint(source, levels, brushSize, source.Bounds);
}
public static IImageOperations<TPixel> OilPaint<TPixel>(this IImageOperations<TPixel> source, int levels, int brushSize)
where TPixel : struct, IPixel<TPixel>
=> source.ApplyProcessor(new OilPaintingProcessor<TPixel>(levels, brushSize));
/// <summary>
/// Alters the colors of the image recreating an oil painting effect.
@ -71,18 +69,8 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> OilPaint<TPixel>(this Image<TPixel> source, int levels, int brushSize, Rectangle rectangle)
public static IImageOperations<TPixel> OilPaint<TPixel>(this IImageOperations<TPixel> source, int levels, int brushSize, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
Guard.MustBeGreaterThan(levels, 0, nameof(levels));
if (brushSize <= 0 || brushSize > source.Height || brushSize > source.Width)
{
throw new ArgumentOutOfRangeException(nameof(brushSize));
}
source.ApplyProcessor(new OilPaintingProcessor<TPixel>(levels, brushSize), rectangle);
return source;
}
=> source.ApplyProcessor(new OilPaintingProcessor<TPixel>(levels, brushSize), rectangle);
}
}

18
src/ImageSharp/Processing/Effects/Pixelate.cs

@ -24,11 +24,9 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="size">The size of the pixels.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Pixelate<TPixel>(this Image<TPixel> source, int size = 4)
public static IImageOperations<TPixel> Pixelate<TPixel>(this IImageOperations<TPixel> source, int size = 4)
where TPixel : struct, IPixel<TPixel>
{
return Pixelate(source, size, source.Bounds);
}
=> source.ApplyProcessor(new PixelateProcessor<TPixel>(size));
/// <summary>
/// Pixelates an image with the given pixel size.
@ -40,16 +38,8 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Pixelate<TPixel>(this Image<TPixel> source, int size, Rectangle rectangle)
public static IImageOperations<TPixel> Pixelate<TPixel>(this IImageOperations<TPixel> source, int size, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
if (size <= 0 || size > source.Height || size > source.Width)
{
throw new ArgumentOutOfRangeException(nameof(size));
}
source.ApplyProcessor(new PixelateProcessor<TPixel>(size), rectangle);
return source;
}
=> source.ApplyProcessor(new PixelateProcessor<TPixel>(size), rectangle);
}
}

66
src/ImageSharp/Processing/ImageProcessor.cs

@ -25,7 +25,7 @@ namespace ImageSharp.Processing
public virtual bool Compand { get; set; } = false;
/// <inheritdoc/>
public void Apply(ImageBase<TPixel> source, Rectangle sourceRectangle)
public void Apply(Image<TPixel> source, Rectangle sourceRectangle)
{
if (this.ParallelOptions == null)
{
@ -34,10 +34,50 @@ namespace ImageSharp.Processing
try
{
this.BeforeApply(source, sourceRectangle);
this.BeforeImageApply(source, sourceRectangle);
this.BeforeApply(source, sourceRectangle);
this.OnApply(source, sourceRectangle);
this.AfterApply(source, sourceRectangle);
foreach (ImageFrame<TPixel> sourceFrame in source.Frames)
{
this.BeforeApply(source, sourceRectangle);
this.OnApply(source, sourceRectangle);
this.AfterApply(source, sourceRectangle);
}
this.AfterImageApply(source, sourceRectangle);
}
#if DEBUG
catch (Exception)
{
throw;
#else
catch (Exception ex)
{
throw new ImageProcessingException($"An error occured when processing the image using {this.GetType().Name}. See the inner exception for more detail.", ex);
#endif
}
}
/// <summary>
/// Applies the processor to just a single ImageBase
/// </summary>
/// <param name="source">the source image</param>
/// <param name="sourceRectangle">the target</param>
public void Apply(ImageBase<TPixel> source, Rectangle sourceRectangle)
{
if (this.ParallelOptions == null)
{
this.ParallelOptions = source.Configuration.ParallelOptions;
}
try
{
this.BeforeApply(source, sourceRectangle);
this.OnApply(source, sourceRectangle);
this.AfterApply(source, sourceRectangle);
}
#if DEBUG
@ -52,6 +92,17 @@ namespace ImageSharp.Processing
}
}
/// <summary>
/// This method is called before the process is applied to prepare the processor.
/// </summary>
/// <param name="source">The source image. Cannot be null.</param>
/// <param name="sourceRectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to draw.
/// </param>
protected virtual void BeforeImageApply(Image<TPixel> source, Rectangle sourceRectangle)
{
}
/// <summary>
/// This method is called before the process is applied to prepare the processor.
/// </summary>
@ -83,5 +134,16 @@ namespace ImageSharp.Processing
protected virtual void AfterApply(ImageBase<TPixel> source, Rectangle sourceRectangle)
{
}
/// <summary>
/// This method is called after the process is applied to prepare the processor.
/// </summary>
/// <param name="source">The source image. Cannot be null.</param>
/// <param name="sourceRectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to draw.
/// </param>
protected virtual void AfterImageApply(Image<TPixel> source, Rectangle sourceRectangle)
{
}
}
}

79
src/ImageSharp/Processing/Overlays/Glow.cs

@ -21,7 +21,7 @@ namespace ImageSharp
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Glow<TPixel>(this Image<TPixel> source)
public static IImageOperations<TPixel> Glow<TPixel>(this IImageOperations<TPixel> source)
where TPixel : struct, IPixel<TPixel>
{
return Glow(source, GraphicsOptions.Default);
@ -34,7 +34,7 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="color">The color to set as the glow.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Glow<TPixel>(this Image<TPixel> source, TPixel color)
public static IImageOperations<TPixel> Glow<TPixel>(this IImageOperations<TPixel> source, TPixel color)
where TPixel : struct, IPixel<TPixel>
{
return Glow(source, color, GraphicsOptions.Default);
@ -47,7 +47,7 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="radius">The the radius.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Glow<TPixel>(this Image<TPixel> source, float radius)
public static IImageOperations<TPixel> Glow<TPixel>(this IImageOperations<TPixel> source, float radius)
where TPixel : struct, IPixel<TPixel>
{
return Glow(source, radius, GraphicsOptions.Default);
@ -62,11 +62,9 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Glow<TPixel>(this Image<TPixel> source, Rectangle rectangle)
public static IImageOperations<TPixel> Glow<TPixel>(this IImageOperations<TPixel> source, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
return Glow(source, rectangle, GraphicsOptions.Default);
}
=> source.Glow(rectangle, GraphicsOptions.Default);
/// <summary>
/// Applies a radial glow effect to an image.
@ -79,11 +77,9 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Glow<TPixel>(this Image<TPixel> source, TPixel color, float radius, Rectangle rectangle)
public static IImageOperations<TPixel> Glow<TPixel>(this IImageOperations<TPixel> source, TPixel color, float radius, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
return Glow(source, color, radius, rectangle, GraphicsOptions.Default);
}
=> source.Glow(color, ValueSize.Absolute(radius), rectangle, GraphicsOptions.Default);
/// <summary>
/// Applies a radial glow effect to an image.
@ -92,11 +88,9 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="options">The options effecting things like blending.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Glow<TPixel>(this Image<TPixel> source, GraphicsOptions options)
public static IImageOperations<TPixel> Glow<TPixel>(this IImageOperations<TPixel> source, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return Glow(source, NamedColors<TPixel>.Black, source.Bounds.Width * .5F, source.Bounds, options);
}
=> source.Glow(NamedColors<TPixel>.Black, ValueSize.PercentageOfWidth(0.5f), options);
/// <summary>
/// Applies a radial glow effect to an image.
@ -106,11 +100,9 @@ namespace ImageSharp
/// <param name="color">The color to set as the glow.</param>
/// <param name="options">The options effecting things like blending.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Glow<TPixel>(this Image<TPixel> source, TPixel color, GraphicsOptions options)
public static IImageOperations<TPixel> Glow<TPixel>(this IImageOperations<TPixel> source, TPixel color, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return Glow(source, color, source.Bounds.Width * .5F, source.Bounds, options);
}
=> source.Glow(color, ValueSize.PercentageOfWidth(0.5f), options);
/// <summary>
/// Applies a radial glow effect to an image.
@ -120,11 +112,9 @@ namespace ImageSharp
/// <param name="radius">The the radius.</param>
/// <param name="options">The options effecting things like blending.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Glow<TPixel>(this Image<TPixel> source, float radius, GraphicsOptions options)
public static IImageOperations<TPixel> Glow<TPixel>(this IImageOperations<TPixel> source, float radius, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return Glow(source, NamedColors<TPixel>.Black, radius, source.Bounds, options);
}
=> source.Glow(NamedColors<TPixel>.Black, ValueSize.Absolute(radius), options);
/// <summary>
/// Applies a radial glow effect to an image.
@ -136,11 +126,9 @@ namespace ImageSharp
/// </param>
/// <param name="options">The options effecting things like blending.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Glow<TPixel>(this Image<TPixel> source, Rectangle rectangle, GraphicsOptions options)
public static IImageOperations<TPixel> Glow<TPixel>(this IImageOperations<TPixel> source, Rectangle rectangle, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return Glow(source, NamedColors<TPixel>.Black, 0, rectangle, options);
}
=> source.Glow(NamedColors<TPixel>.Black, ValueSize.PercentageOfWidth(0.5f), rectangle, options);
/// <summary>
/// Applies a radial glow effect to an image.
@ -154,12 +142,37 @@ namespace ImageSharp
/// </param>
/// <param name="options">The options effecting things like blending.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Glow<TPixel>(this Image<TPixel> source, TPixel color, float radius, Rectangle rectangle, GraphicsOptions options)
public static IImageOperations<TPixel> Glow<TPixel>(this IImageOperations<TPixel> source, TPixel color, float radius, Rectangle rectangle, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
var processor = new GlowProcessor<TPixel>(color, options) { Radius = radius, };
source.ApplyProcessor(processor, rectangle);
return source;
}
=> source.Glow(color, ValueSize.Absolute(radius), rectangle, options);
/// <summary>
/// Applies a radial glow effect to an image.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="color">The color to set as the glow.</param>
/// <param name="radius">The the radius.</param>
/// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <param name="options">The options effecting things like blending.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
private static IImageOperations<TPixel> Glow<TPixel>(this IImageOperations<TPixel> source, TPixel color, ValueSize radius, Rectangle rectangle, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
=> source.ApplyProcessor(new GlowProcessor<TPixel>(color, radius, options), rectangle);
/// <summary>
/// Applies a radial glow effect to an image.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="color">The color to set as the glow.</param>
/// <param name="radius">The the radius.</param>
/// <param name="options">The options effecting things like blending.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
private static IImageOperations<TPixel> Glow<TPixel>(this IImageOperations<TPixel> source, TPixel color, ValueSize radius, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
=> source.ApplyProcessor(new GlowProcessor<TPixel>(color, radius, options));
}
}

54
src/ImageSharp/Processing/Overlays/Vignette.cs

@ -21,7 +21,7 @@ namespace ImageSharp
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Vignette<TPixel>(this Image<TPixel> source)
public static IImageOperations<TPixel> Vignette<TPixel>(this IImageOperations<TPixel> source)
where TPixel : struct, IPixel<TPixel>
{
return Vignette(source, GraphicsOptions.Default);
@ -34,7 +34,7 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="color">The color to set as the vignette.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Vignette<TPixel>(this Image<TPixel> source, TPixel color)
public static IImageOperations<TPixel> Vignette<TPixel>(this IImageOperations<TPixel> source, TPixel color)
where TPixel : struct, IPixel<TPixel>
{
return Vignette(source, color, GraphicsOptions.Default);
@ -48,7 +48,7 @@ namespace ImageSharp
/// <param name="radiusX">The the x-radius.</param>
/// <param name="radiusY">The the y-radius.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Vignette<TPixel>(this Image<TPixel> source, float radiusX, float radiusY)
public static IImageOperations<TPixel> Vignette<TPixel>(this IImageOperations<TPixel> source, float radiusX, float radiusY)
where TPixel : struct, IPixel<TPixel>
{
return Vignette(source, radiusX, radiusY, GraphicsOptions.Default);
@ -63,7 +63,7 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Vignette<TPixel>(this Image<TPixel> source, Rectangle rectangle)
public static IImageOperations<TPixel> Vignette<TPixel>(this IImageOperations<TPixel> source, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
return Vignette(source, rectangle, GraphicsOptions.Default);
@ -81,11 +81,9 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Vignette<TPixel>(this Image<TPixel> source, TPixel color, float radiusX, float radiusY, Rectangle rectangle)
public static IImageOperations<TPixel> Vignette<TPixel>(this IImageOperations<TPixel> source, TPixel color, float radiusX, float radiusY, Rectangle rectangle)
where TPixel : struct, IPixel<TPixel>
{
return Vignette(source, color, radiusX, radiusY, rectangle, GraphicsOptions.Default);
}
=> source.Vignette(color, radiusX, radiusY, rectangle, GraphicsOptions.Default);
/// <summary>
/// Applies a radial vignette effect to an image.
@ -94,11 +92,9 @@ namespace ImageSharp
/// <param name="source">The image this method extends.</param>
/// <param name="options">The options effecting pixel blending.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Vignette<TPixel>(this Image<TPixel> source, GraphicsOptions options)
public static IImageOperations<TPixel> Vignette<TPixel>(this IImageOperations<TPixel> source, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return Vignette(source, NamedColors<TPixel>.Black, source.Bounds.Width * .5F, source.Bounds.Height * .5F, source.Bounds, options);
}
=> source.Vignette(NamedColors<TPixel>.Black, ValueSize.PercentageOfWidth(.5f), ValueSize.PercentageOfHeight(.5f), options);
/// <summary>
/// Applies a radial vignette effect to an image.
@ -108,11 +104,9 @@ namespace ImageSharp
/// <param name="color">The color to set as the vignette.</param>
/// <param name="options">The options effecting pixel blending.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Vignette<TPixel>(this Image<TPixel> source, TPixel color, GraphicsOptions options)
public static IImageOperations<TPixel> Vignette<TPixel>(this IImageOperations<TPixel> source, TPixel color, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return Vignette(source, color, source.Bounds.Width * .5F, source.Bounds.Height * .5F, source.Bounds, options);
}
=> source.Vignette(color, 0, 0, options);
/// <summary>
/// Applies a radial vignette effect to an image.
@ -123,11 +117,9 @@ namespace ImageSharp
/// <param name="radiusY">The the y-radius.</param>
/// <param name="options">The options effecting pixel blending.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Vignette<TPixel>(this Image<TPixel> source, float radiusX, float radiusY, GraphicsOptions options)
public static IImageOperations<TPixel> Vignette<TPixel>(this IImageOperations<TPixel> source, float radiusX, float radiusY, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return Vignette(source, NamedColors<TPixel>.Black, radiusX, radiusY, source.Bounds, options);
}
=> source.Vignette(NamedColors<TPixel>.Black, radiusX, radiusY, options);
/// <summary>
/// Applies a radial vignette effect to an image.
@ -139,11 +131,9 @@ namespace ImageSharp
/// </param>
/// <param name="options">The options effecting pixel blending.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Vignette<TPixel>(this Image<TPixel> source, Rectangle rectangle, GraphicsOptions options)
public static IImageOperations<TPixel> Vignette<TPixel>(this IImageOperations<TPixel> source, Rectangle rectangle, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
return Vignette(source, NamedColors<TPixel>.Black, 0, 0, rectangle, options);
}
=> source.Vignette(NamedColors<TPixel>.Black, 0, 0, rectangle, options);
/// <summary>
/// Applies a radial vignette effect to an image.
@ -158,12 +148,16 @@ namespace ImageSharp
/// </param>
/// <param name="options">The options effecting pixel blending.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Vignette<TPixel>(this Image<TPixel> source, TPixel color, float radiusX, float radiusY, Rectangle rectangle, GraphicsOptions options)
public static IImageOperations<TPixel> Vignette<TPixel>(this IImageOperations<TPixel> source, TPixel color, float radiusX, float radiusY, Rectangle rectangle, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
{
var processor = new VignetteProcessor<TPixel>(color, options) { RadiusX = radiusX, RadiusY = radiusY };
source.ApplyProcessor(processor, rectangle);
return source;
}
=> source.Vignette(color, radiusX, radiusY, rectangle, options);
private static IImageOperations<TPixel> Vignette<TPixel>(this IImageOperations<TPixel> source, TPixel color, ValueSize radiusX, ValueSize radiusY, Rectangle rectangle, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
=> source.ApplyProcessor(new VignetteProcessor<TPixel>(color, radiusX, radiusY, options), rectangle);
private static IImageOperations<TPixel> Vignette<TPixel>(this IImageOperations<TPixel> source, TPixel color, ValueSize radiusX, ValueSize radiusY, GraphicsOptions options)
where TPixel : struct, IPixel<TPixel>
=> source.ApplyProcessor(new VignetteProcessor<TPixel>(color, radiusX, radiusY, options));
}
}

2
src/ImageSharp/Processing/Processors/ColorMatrix/PolaroidProcessor.cs

@ -53,7 +53,7 @@ namespace ImageSharp.Processing.Processors
protected override void AfterApply(ImageBase<TPixel> source, Rectangle sourceRectangle)
{
new VignetteProcessor<TPixel>(veryDarkOrange, this.options).Apply(source, sourceRectangle);
new GlowProcessor<TPixel>(lightOrange, this.options) { Radius = source.Width / 4F }.Apply(source, sourceRectangle);
new GlowProcessor<TPixel>(lightOrange, source.Width / 4F, this.options).Apply(source, sourceRectangle);
}
}
}

5
src/ImageSharp/Processing/Processors/Effects/OilPaintingProcessor.cs

@ -51,6 +51,11 @@ namespace ImageSharp.Processing.Processors
/// <inheritdoc/>
protected override void OnApply(ImageBase<TPixel> source, Rectangle sourceRectangle)
{
if (this.BrushSize <= 0 || this.BrushSize > source.Height || this.BrushSize > source.Width)
{
throw new ArgumentOutOfRangeException(nameof(this.BrushSize));
}
int startY = sourceRectangle.Y;
int endY = sourceRectangle.Bottom;
int startX = sourceRectangle.X;

13
src/ImageSharp/Processing/Processors/Effects/PixelateProcessor.cs

@ -29,23 +29,28 @@ namespace ImageSharp.Processing.Processors
public PixelateProcessor(int size)
{
Guard.MustBeGreaterThan(size, 0, nameof(size));
this.Value = size;
this.Size = size;
}
/// <summary>
/// Gets or the pixel size.
/// </summary>
public int Value { get; }
public int Size { get; }
/// <inheritdoc/>
protected override void OnApply(ImageBase<TPixel> source, Rectangle sourceRectangle)
{
if (this.Size <= 0 || this.Size > source.Height || this.Size > source.Width)
{
throw new ArgumentOutOfRangeException(nameof(this.Size));
}
int startY = sourceRectangle.Y;
int endY = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;
int size = this.Value;
int offset = this.Value / 2;
int size = this.Size;
int offset = this.Size / 2;
// Align start/end positions.
int minX = Math.Max(0, startX);

11
src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs

@ -27,11 +27,13 @@ namespace ImageSharp.Processing.Processors
/// Initializes a new instance of the <see cref="GlowProcessor{TPixel}" /> class.
/// </summary>
/// <param name="color">The color or the glow.</param>
/// <param name="radius">The radius of the glow.</param>
/// <param name="options">The options effecting blending and composition.</param>
public GlowProcessor(TPixel color, GraphicsOptions options)
public GlowProcessor(TPixel color, ValueSize radius, GraphicsOptions options)
{
this.options = options;
this.GlowColor = color;
this.Radius = radius;
this.blender = PixelOperations<TPixel>.Instance.GetPixelBlender(this.options.BlenderMode);
}
@ -43,7 +45,7 @@ namespace ImageSharp.Processing.Processors
/// <summary>
/// Gets or sets the the radius.
/// </summary>
public float Radius { get; set; }
public ValueSize Radius { get; set; }
/// <inheritdoc/>
protected override void OnApply(ImageBase<TPixel> source, Rectangle sourceRectangle)
@ -54,7 +56,10 @@ namespace ImageSharp.Processing.Processors
int endX = sourceRectangle.Right;
TPixel glowColor = this.GlowColor;
Vector2 centre = Rectangle.Center(sourceRectangle);
float maxDistance = this.Radius > 0 ? MathF.Min(this.Radius, sourceRectangle.Width * .5F) : sourceRectangle.Width * .5F;
var finalRadius = this.Radius.Calculate(source.Bounds.Size);
float maxDistance = finalRadius > 0 ? MathF.Min(finalRadius, sourceRectangle.Width * .5F) : sourceRectangle.Width * .5F;
// Align start/end positions.
int minX = Math.Max(0, startX);

28
src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs

@ -27,11 +27,26 @@ namespace ImageSharp.Processing.Processors
/// Initializes a new instance of the <see cref="VignetteProcessor{TPixel}" /> class.
/// </summary>
/// <param name="color">The color of the vignette.</param>
/// <param name="radiusX">The x-radius.</param>
/// <param name="radiusY">The y-radius.</param>
/// <param name="options">The options effecting blending and composition.</param>
public VignetteProcessor(TPixel color, GraphicsOptions options)
public VignetteProcessor(TPixel color, ValueSize radiusX, ValueSize radiusY, GraphicsOptions options)
{
this.VignetteColor = color;
this.RadiusX = radiusX;
this.RadiusY = radiusY;
this.options = options;
this.blender = PixelOperations<TPixel>.Instance.GetPixelBlender(this.options.BlenderMode);
}
/// <summary>
/// Initializes a new instance of the <see cref="VignetteProcessor{TPixel}" /> class.
/// </summary>
/// <param name="color">The color of the vignette.</param>
/// <param name="options">The options effecting blending and composition.</param>
public VignetteProcessor(TPixel color, GraphicsOptions options)
{
this.VignetteColor = color;
this.options = options;
this.blender = PixelOperations<TPixel>.Instance.GetPixelBlender(this.options.BlenderMode);
}
@ -44,12 +59,12 @@ namespace ImageSharp.Processing.Processors
/// <summary>
/// Gets or sets the the x-radius.
/// </summary>
public float RadiusX { get; set; }
public ValueSize RadiusX { get; set; }
/// <summary>
/// Gets or sets the the y-radius.
/// </summary>
public float RadiusY { get; set; }
public ValueSize RadiusY { get; set; }
/// <inheritdoc/>
protected override void OnApply(ImageBase<TPixel> source, Rectangle sourceRectangle)
@ -60,8 +75,11 @@ namespace ImageSharp.Processing.Processors
int endX = sourceRectangle.Right;
TPixel vignetteColor = this.VignetteColor;
Vector2 centre = Rectangle.Center(sourceRectangle);
float rX = this.RadiusX > 0 ? MathF.Min(this.RadiusX, sourceRectangle.Width * .5F) : sourceRectangle.Width * .5F;
float rY = this.RadiusY > 0 ? MathF.Min(this.RadiusY, sourceRectangle.Height * .5F) : sourceRectangle.Height * .5F;
var finalradiusX = this.RadiusX.Calculate(source.Bounds.Size);
var finalradiusY = this.RadiusY.Calculate(source.Bounds.Size);
float rX = finalradiusX > 0 ? MathF.Min(finalradiusX, sourceRectangle.Width * .5F) : sourceRectangle.Width * .5F;
float rY = finalradiusY > 0 ? MathF.Min(finalradiusY, sourceRectangle.Height * .5F) : sourceRectangle.Height * .5F;
float maxDistance = MathF.Sqrt((rX * rX) + (rY * rY));
// Align start/end positions.

103
src/ImageSharp/Processing/Processors/Transforms/AutoRotateProcessor.cs

@ -0,0 +1,103 @@
// <copyright file="FlipProcessor.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Processing.Processors
{
using System;
using System.Threading.Tasks;
using ImageSharp.Memory;
using ImageSharp.PixelFormats;
using SixLabors.Primitives;
/// <summary>
/// Adjusts an image so that its orientation is suitable for viewing. Adjustments are based on EXIF metadata embedded in the image.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
internal class AutoRotateProcessor<TPixel> : ImageProcessor<TPixel>
where TPixel : struct, IPixel<TPixel>
{
/// <summary>
/// Initializes a new instance of the <see cref="AutoRotateProcessor{TPixel}"/> class.
/// </summary>
public AutoRotateProcessor()
{
}
/// <inheritdoc/>
protected override void OnApply(ImageBase<TPixel> sourceBase, Rectangle sourceRectangle)
{
// can only apply to the origional image
var source = sourceBase as Image<TPixel>;
if (source != null)
{
Orientation orientation = GetExifOrientation(source);
switch (orientation)
{
case Orientation.TopRight:
new FlipProcessor<TPixel>(FlipType.Horizontal).Apply(source, sourceRectangle);
break;
case Orientation.BottomRight:
new RotateProcessor<TPixel>() { Angle = (int)RotateType.Rotate180, Expand = false }.Apply(source, sourceRectangle);
break;
case Orientation.BottomLeft:
new FlipProcessor<TPixel>(FlipType.Vertical).Apply(source, sourceRectangle);
break;
case Orientation.LeftTop:
new RotateProcessor<TPixel>() { Angle = (int)RotateType.Rotate90, Expand = false }.Apply(source, sourceRectangle);
new FlipProcessor<TPixel>(FlipType.Horizontal).Apply(source, sourceRectangle);
break;
case Orientation.RightTop:
new RotateProcessor<TPixel>() { Angle = (int)RotateType.Rotate90, Expand = false }.Apply(source, sourceRectangle);
break;
case Orientation.RightBottom:
new FlipProcessor<TPixel>(FlipType.Vertical).Apply(source, sourceRectangle);
new RotateProcessor<TPixel>() { Angle = (int)RotateType.Rotate270, Expand = false }.Apply(source, sourceRectangle);
break;
case Orientation.LeftBottom:
new RotateProcessor<TPixel>() { Angle = (int)RotateType.Rotate270, Expand = false }.Apply(source, sourceRectangle);
break;
case Orientation.Unknown:
case Orientation.TopLeft:
default:
break;
}
}
}
/// <summary>
/// Returns the current EXIF orientation
/// </summary>
/// <param name="source">The image to auto rotate.</param>
/// <returns>The <see cref="Orientation"/></returns>
private static Orientation GetExifOrientation(Image<TPixel> source)
{
if (source.MetaData.ExifProfile == null)
{
return Orientation.Unknown;
}
ExifValue value = source.MetaData.ExifProfile.GetValue(ExifTag.Orientation);
if (value == null)
{
return Orientation.Unknown;
}
var orientation = (Orientation)value.Value;
source.MetaData.ExifProfile.SetValue(ExifTag.Orientation, (ushort)Orientation.TopLeft);
return orientation;
}
}
}

12
src/ImageSharp/Processing/Processors/Transforms/ResamplingWeightedProcessor.cs

@ -46,19 +46,19 @@ namespace ImageSharp.Processing.Processors
public IResampler Sampler { get; }
/// <summary>
/// Gets the width.
/// Gets or sets the width.
/// </summary>
public int Width { get; }
public int Width { get; protected set; }
/// <summary>
/// Gets the height.
/// Gets or sets the height.
/// </summary>
public int Height { get; }
public int Height { get; protected set; }
/// <summary>
/// Gets the resize rectangle.
/// Gets or sets the resize rectangle.
/// </summary>
public Rectangle ResizeRectangle { get; }
public Rectangle ResizeRectangle { get; protected set; }
/// <summary>
/// Gets or sets the horizontal weights.

64
src/ImageSharp/Processing/Transforms/AutoOrient.cs

@ -20,68 +20,8 @@ namespace ImageSharp
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image to auto rotate.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
public static Image<TPixel> AutoOrient<TPixel>(this Image<TPixel> source)
public static IImageOperations<TPixel> AutoOrient<TPixel>(this IImageOperations<TPixel> source)
where TPixel : struct, IPixel<TPixel>
{
Orientation orientation = GetExifOrientation(source);
switch (orientation)
{
case Orientation.TopRight:
return source.Flip(FlipType.Horizontal);
case Orientation.BottomRight:
return source.Rotate(RotateType.Rotate180);
case Orientation.BottomLeft:
return source.Flip(FlipType.Vertical);
case Orientation.LeftTop:
return source.Rotate(RotateType.Rotate90)
.Flip(FlipType.Horizontal);
case Orientation.RightTop:
return source.Rotate(RotateType.Rotate90);
case Orientation.RightBottom:
return source.Flip(FlipType.Vertical)
.Rotate(RotateType.Rotate270);
case Orientation.LeftBottom:
return source.Rotate(RotateType.Rotate270);
case Orientation.Unknown:
case Orientation.TopLeft:
default:
return source;
}
}
/// <summary>
/// Returns the current EXIF orientation
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image to auto rotate.</param>
/// <returns>The <see cref="Orientation"/></returns>
private static Orientation GetExifOrientation<TPixel>(Image<TPixel> source)
where TPixel : struct, IPixel<TPixel>
{
if (source.MetaData.ExifProfile == null)
{
return Orientation.Unknown;
}
ExifValue value = source.MetaData.ExifProfile.GetValue(ExifTag.Orientation);
if (value == null)
{
return Orientation.Unknown;
}
var orientation = (Orientation)value.Value;
source.MetaData.ExifProfile.SetValue(ExifTag.Orientation, (ushort)Orientation.TopLeft);
return orientation;
}
=> source.ApplyProcessor(new Processing.Processors.AutoRotateProcessor<TPixel>());
}
}

15
src/ImageSharp/Processing/Transforms/Crop.cs

@ -25,11 +25,9 @@ namespace ImageSharp
/// <param name="width">The target image width.</param>
/// <param name="height">The target image height.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
public static Image<TPixel> Crop<TPixel>(this Image<TPixel> source, int width, int height)
public static IImageOperations<TPixel> Crop<TPixel>(this IImageOperations<TPixel> source, int width, int height)
where TPixel : struct, IPixel<TPixel>
{
return Crop(source, new Rectangle(0, 0, width, height));
}
=> Crop(source, new Rectangle(0, 0, width, height));
/// <summary>
/// Crops an image to the given rectangle.
@ -40,13 +38,8 @@ namespace ImageSharp
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to retain.
/// </param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
public static Image<TPixel> Crop<TPixel>(this Image<TPixel> source, Rectangle cropRectangle)
public static IImageOperations<TPixel> Crop<TPixel>(this IImageOperations<TPixel> source, Rectangle cropRectangle)
where TPixel : struct, IPixel<TPixel>
{
CropProcessor<TPixel> processor = new CropProcessor<TPixel>(cropRectangle);
source.ApplyProcessor(processor, source.Bounds);
return source;
}
=> source.ApplyProcessor(new CropProcessor<TPixel>(cropRectangle));
}
}

9
src/ImageSharp/Processing/Transforms/EntropyCrop.cs

@ -23,13 +23,8 @@ namespace ImageSharp
/// <param name="source">The image to crop.</param>
/// <param name="threshold">The threshold for entropic density.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
public static Image<TPixel> EntropyCrop<TPixel>(this Image<TPixel> source, float threshold = .5f)
public static IImageOperations<TPixel> EntropyCrop<TPixel>(this IImageOperations<TPixel> source, float threshold = .5f)
where TPixel : struct, IPixel<TPixel>
{
EntropyCropProcessor<TPixel> processor = new EntropyCropProcessor<TPixel>(threshold);
source.ApplyProcessor(processor, source.Bounds);
return source;
}
=> source.ApplyProcessor(new EntropyCropProcessor<TPixel>(threshold));
}
}

9
src/ImageSharp/Processing/Transforms/Flip.cs

@ -24,13 +24,8 @@ namespace ImageSharp
/// <param name="source">The image to rotate, flip, or both.</param>
/// <param name="flipType">The <see cref="FlipType"/> to perform the flip.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
public static Image<TPixel> Flip<TPixel>(this Image<TPixel> source, FlipType flipType)
public static IImageOperations<TPixel> Flip<TPixel>(this IImageOperations<TPixel> source, FlipType flipType)
where TPixel : struct, IPixel<TPixel>
{
FlipProcessor<TPixel> processor = new FlipProcessor<TPixel>(flipType);
source.ApplyProcessor(processor, source.Bounds);
return source;
}
=> source.ApplyProcessor(new FlipProcessor<TPixel>(flipType));
}
}

2
src/ImageSharp/Processing/Transforms/Pad.cs

@ -26,7 +26,7 @@ namespace ImageSharp
/// <param name="width">The new width.</param>
/// <param name="height">The new height.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Pad<TPixel>(this Image<TPixel> source, int width, int height)
public static IImageOperations<TPixel> Pad<TPixel>(this IImageOperations<TPixel> source, int width, int height)
where TPixel : struct, IPixel<TPixel>
{
ResizeOptions options = new ResizeOptions

118
src/ImageSharp/Processing/Transforms/Resize.cs

@ -24,23 +24,28 @@ namespace ImageSharp
/// <param name="options">The resize options.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
/// <remarks>Passing zero for one of height or width within the resize options will automatically preserve the aspect ratio of the original image</remarks>
public static Image<TPixel> Resize<TPixel>(this Image<TPixel> source, ResizeOptions options)
public static IImageOperations<TPixel> Resize<TPixel>(this IImageOperations<TPixel> source, ResizeOptions options)
where TPixel : struct, IPixel<TPixel>
{
// Ensure size is populated across both dimensions.
if (options.Size.Width == 0 && options.Size.Height > 0)
return source.Run(img =>
{
options.Size = new Size((int)MathF.Round(source.Width * options.Size.Height / (float)source.Height), options.Size.Height);
}
// cheat and bound through a run, inside here we should just be mutating, this reallt needs moving over to a processor
if (options.Size.Height == 0 && options.Size.Width > 0)
{
options.Size = new Size(options.Size.Width, (int)MathF.Round(source.Height * options.Size.Width / (float)source.Width));
}
// Ensure size is populated across both dimensions.
if (options.Size.Width == 0 && options.Size.Height > 0)
{
options.Size = new Size((int)MathF.Round(img.Width * options.Size.Height / (float)img.Height), options.Size.Height);
}
if (options.Size.Height == 0 && options.Size.Width > 0)
{
options.Size = new Size(options.Size.Width, (int)MathF.Round(img.Height * options.Size.Width / (float)img.Width));
}
Rectangle targetRectangle = ResizeHelper.CalculateTargetLocationAndBounds(source, options);
Rectangle targetRectangle = ResizeHelper.CalculateTargetLocationAndBounds(img, options);
return Resize(source, options.Size.Width, options.Size.Height, options.Sampler, source.Bounds, targetRectangle, options.Compand);
img.Mutate(x => Resize(x, options.Size.Width, options.Size.Height, options.Sampler, targetRectangle, options.Compand));
});
}
/// <summary>
@ -51,7 +56,7 @@ namespace ImageSharp
/// <param name="size">The target image size.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
/// <remarks>Passing zero for one of height or width will automatically preserve the aspect ratio of the original image</remarks>
public static Image<TPixel> Resize<TPixel>(this Image<TPixel> source, Size size)
public static IImageOperations<TPixel> Resize<TPixel>(this IImageOperations<TPixel> source, Size size)
where TPixel : struct, IPixel<TPixel>
{
return Resize(source, size.Width, size.Height, new BicubicResampler(), false);
@ -66,7 +71,7 @@ namespace ImageSharp
/// <param name="compand">Whether to compress and expand the image color-space to gamma correct the image during processing.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
/// <remarks>Passing zero for one of height or width will automatically preserve the aspect ratio of the original image</remarks>
public static Image<TPixel> Resize<TPixel>(this Image<TPixel> source, Size size, bool compand)
public static IImageOperations<TPixel> Resize<TPixel>(this IImageOperations<TPixel> source, Size size, bool compand)
where TPixel : struct, IPixel<TPixel>
{
return Resize(source, size.Width, size.Height, new BicubicResampler(), compand);
@ -81,7 +86,7 @@ namespace ImageSharp
/// <param name="height">The target image height.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
/// <remarks>Passing zero for one of height or width will automatically preserve the aspect ratio of the original image</remarks>
public static Image<TPixel> Resize<TPixel>(this Image<TPixel> source, int width, int height)
public static IImageOperations<TPixel> Resize<TPixel>(this IImageOperations<TPixel> source, int width, int height)
where TPixel : struct, IPixel<TPixel>
{
return Resize(source, width, height, new BicubicResampler(), false);
@ -97,7 +102,7 @@ namespace ImageSharp
/// <param name="compand">Whether to compress and expand the image color-space to gamma correct the image during processing.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
/// <remarks>Passing zero for one of height or width will automatically preserve the aspect ratio of the original image</remarks>
public static Image<TPixel> Resize<TPixel>(this Image<TPixel> source, int width, int height, bool compand)
public static IImageOperations<TPixel> Resize<TPixel>(this IImageOperations<TPixel> source, int width, int height, bool compand)
where TPixel : struct, IPixel<TPixel>
{
return Resize(source, width, height, new BicubicResampler(), compand);
@ -113,7 +118,7 @@ namespace ImageSharp
/// <param name="sampler">The <see cref="IResampler"/> to perform the resampling.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
/// <remarks>Passing zero for one of height or width will automatically preserve the aspect ratio of the original image</remarks>
public static Image<TPixel> Resize<TPixel>(this Image<TPixel> source, int width, int height, IResampler sampler)
public static IImageOperations<TPixel> Resize<TPixel>(this IImageOperations<TPixel> source, int width, int height, IResampler sampler)
where TPixel : struct, IPixel<TPixel>
{
return Resize(source, width, height, sampler, false);
@ -130,10 +135,10 @@ namespace ImageSharp
/// <param name="compand">Whether to compress and expand the image color-space to gamma correct the image during processing.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
/// <remarks>Passing zero for one of height or width will automatically preserve the aspect ratio of the original image</remarks>
public static Image<TPixel> Resize<TPixel>(this Image<TPixel> source, int width, int height, IResampler sampler, bool compand)
public static IImageOperations<TPixel> Resize<TPixel>(this IImageOperations<TPixel> source, int width, int height, IResampler sampler, bool compand)
where TPixel : struct, IPixel<TPixel>
{
return Resize(source, width, height, sampler, source.Bounds, new Rectangle(0, 0, width, height), compand);
return Resize(source, width, height, sampler, new Rectangle(0, 0, width, height), compand);
}
/// <summary>
@ -154,28 +159,69 @@ namespace ImageSharp
/// <param name="compand">Whether to compress and expand the image color-space to gamma correct the image during processing.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
/// <remarks>Passing zero for one of height or width will automatically preserve the aspect ratio of the original image</remarks>
public static Image<TPixel> Resize<TPixel>(this Image<TPixel> source, int width, int height, IResampler sampler, Rectangle sourceRectangle, Rectangle targetRectangle, bool compand)
public static IImageOperations<TPixel> Resize<TPixel>(this IImageOperations<TPixel> source, int width, int height, IResampler sampler, Rectangle sourceRectangle, Rectangle targetRectangle, bool compand)
where TPixel : struct, IPixel<TPixel>
{
if (width == 0 && height > 0)
{
width = (int)MathF.Round(source.Width * height / (float)source.Height);
targetRectangle.Width = width;
}
return source.Run(img =>
{
// todo : stop cheeting here and move this stuff into the processors itself
if (width == 0 && height > 0)
{
width = (int)MathF.Round(img.Width * height / (float)img.Height);
targetRectangle.Width = width;
}
if (height == 0 && width > 0)
{
height = (int)MathF.Round(img.Height * width / (float)img.Width);
targetRectangle.Height = height;
}
Guard.MustBeGreaterThan(width, 0, nameof(width));
Guard.MustBeGreaterThan(height, 0, nameof(height));
img.Mutate(x => x.ApplyProcessor(new ResizeProcessor<TPixel>(sampler, width, height, targetRectangle) { Compand = compand }, sourceRectangle));
});
}
if (height == 0 && width > 0)
/// <summary>
/// Resizes an image to the given width and height with the given sampler and
/// source rectangle.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image to resize.</param>
/// <param name="width">The target image width.</param>
/// <param name="height">The target image height.</param>
/// <param name="sampler">The <see cref="IResampler"/> to perform the resampling.</param>
/// <param name="targetRectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the target image object to draw to.
/// </param>
/// <param name="compand">Whether to compress and expand the image color-space to gamma correct the image during processing.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
/// <remarks>Passing zero for one of height or width will automatically preserve the aspect ratio of the original image</remarks>
public static IImageOperations<TPixel> Resize<TPixel>(this IImageOperations<TPixel> source, int width, int height, IResampler sampler, Rectangle targetRectangle, bool compand)
where TPixel : struct, IPixel<TPixel>
{
return source.Run(img =>
{
height = (int)MathF.Round(source.Height * width / (float)source.Width);
targetRectangle.Height = height;
}
Guard.MustBeGreaterThan(width, 0, nameof(width));
Guard.MustBeGreaterThan(height, 0, nameof(height));
var processor = new ResizeProcessor<TPixel>(sampler, width, height, targetRectangle) { Compand = compand };
source.ApplyProcessor(processor, sourceRectangle);
return source;
// todo : stop cheeting here and move this stuff into the processors itself
if (width == 0 && height > 0)
{
width = (int)MathF.Round(img.Width * height / (float)img.Height);
targetRectangle.Width = width;
}
if (height == 0 && width > 0)
{
height = (int)MathF.Round(img.Height * width / (float)img.Width);
targetRectangle.Height = height;
}
Guard.MustBeGreaterThan(width, 0, nameof(width));
Guard.MustBeGreaterThan(height, 0, nameof(height));
img.Mutate(x => x.ApplyProcessor(new ResizeProcessor<TPixel>(sampler, width, height, targetRectangle) { Compand = compand }));
});
}
}
}

17
src/ImageSharp/Processing/Transforms/Rotate.cs

@ -24,7 +24,7 @@ namespace ImageSharp
/// <param name="source">The image to rotate.</param>
/// <param name="degrees">The angle in degrees to perform the rotation.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
public static Image<TPixel> Rotate<TPixel>(this Image<TPixel> source, float degrees)
public static IImageOperations<TPixel> Rotate<TPixel>(this IImageOperations<TPixel> source, float degrees)
where TPixel : struct, IPixel<TPixel>
{
return Rotate(source, degrees, true);
@ -37,11 +37,9 @@ namespace ImageSharp
/// <param name="source">The image to rotate.</param>
/// <param name="rotateType">The <see cref="RotateType"/> to perform the rotation.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
public static Image<TPixel> Rotate<TPixel>(this Image<TPixel> source, RotateType rotateType)
public static IImageOperations<TPixel> Rotate<TPixel>(this IImageOperations<TPixel> source, RotateType rotateType)
where TPixel : struct, IPixel<TPixel>
{
return Rotate(source, (float)rotateType, false);
}
=> Rotate(source, (float)rotateType, false);
/// <summary>
/// Rotates an image by the given angle in degrees.
@ -51,13 +49,8 @@ namespace ImageSharp
/// <param name="degrees">The angle in degrees to perform the rotation.</param>
/// <param name="expand">Whether to expand the image to fit the rotated result.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
public static Image<TPixel> Rotate<TPixel>(this Image<TPixel> source, float degrees, bool expand)
public static IImageOperations<TPixel> Rotate<TPixel>(this IImageOperations<TPixel> source, float degrees, bool expand)
where TPixel : struct, IPixel<TPixel>
{
RotateProcessor<TPixel> processor = new RotateProcessor<TPixel> { Angle = degrees, Expand = expand };
source.ApplyProcessor(processor, source.Bounds);
return source;
}
=> source.ApplyProcessor(new RotateProcessor<TPixel> { Angle = degrees, Expand = expand });
}
}

2
src/ImageSharp/Processing/Transforms/RotateFlip.cs

@ -24,7 +24,7 @@ namespace ImageSharp
/// <param name="rotateType">The <see cref="RotateType"/> to perform the rotation.</param>
/// <param name="flipType">The <see cref="FlipType"/> to perform the flip.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
public static Image<TPixel> RotateFlip<TPixel>(this Image<TPixel> source, RotateType rotateType, FlipType flipType)
public static IImageOperations<TPixel> RotateFlip<TPixel>(this IImageOperations<TPixel> source, RotateType rotateType, FlipType flipType)
where TPixel : struct, IPixel<TPixel>
{
return source.Rotate(rotateType).Flip(flipType);

11
src/ImageSharp/Processing/Transforms/Skew.cs

@ -24,7 +24,7 @@ namespace ImageSharp
/// <param name="degreesX">The angle in degrees to perform the rotation along the x-axis.</param>
/// <param name="degreesY">The angle in degrees to perform the rotation along the y-axis.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
public static Image<TPixel> Skew<TPixel>(this Image<TPixel> source, float degreesX, float degreesY)
public static IImageOperations<TPixel> Skew<TPixel>(this IImageOperations<TPixel> source, float degreesX, float degreesY)
where TPixel : struct, IPixel<TPixel>
{
return Skew(source, degreesX, degreesY, true);
@ -39,13 +39,8 @@ namespace ImageSharp
/// <param name="degreesY">The angle in degrees to perform the rotation along the y-axis.</param>
/// <param name="expand">Whether to expand the image to fit the skewed result.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
public static Image<TPixel> Skew<TPixel>(this Image<TPixel> source, float degreesX, float degreesY, bool expand)
public static IImageOperations<TPixel> Skew<TPixel>(this IImageOperations<TPixel> source, float degreesX, float degreesY, bool expand)
where TPixel : struct, IPixel<TPixel>
{
SkewProcessor<TPixel> processor = new SkewProcessor<TPixel> { AngleX = degreesX, AngleY = degreesY, Expand = expand };
source.ApplyProcessor(processor, source.Bounds);
return source;
}
=> source.ApplyProcessor(new SkewProcessor<TPixel> { AngleX = degreesX, AngleY = degreesY, Expand = expand });
}
}

45
src/ImageSharp/Quantizers/Quantize.cs

@ -24,7 +24,7 @@ namespace ImageSharp
/// <param name="mode">The quantization mode to apply to perform the operation.</param>
/// <param name="maxColors">The maximum number of colors to return. Defaults to 256.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Quantize<TPixel>(this Image<TPixel> source, Quantization mode = Quantization.Octree, int maxColors = 256)
public static IImageOperations<TPixel> Quantize<TPixel>(this IImageOperations<TPixel> source, Quantization mode = Quantization.Octree, int maxColors = 256)
where TPixel : struct, IPixel<TPixel>
{
IQuantizer<TPixel> quantizer;
@ -54,31 +54,34 @@ namespace ImageSharp
/// <param name="quantizer">The quantizer to apply to perform the operation.</param>
/// <param name="maxColors">The maximum number of colors to return.</param>
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Quantize<TPixel>(this Image<TPixel> source, IQuantizer<TPixel> quantizer, int maxColors)
public static IImageOperations<TPixel> Quantize<TPixel>(this IImageOperations<TPixel> source, IQuantizer<TPixel> quantizer, int maxColors)
where TPixel : struct, IPixel<TPixel>
{
QuantizedImage<TPixel> quantized = quantizer.Quantize(source, maxColors);
int palleteCount = quantized.Palette.Length - 1;
using (PixelAccessor<TPixel> pixels = new PixelAccessor<TPixel>(quantized.Width, quantized.Height))
return source.Run(img =>
{
Parallel.For(
0,
pixels.Height,
source.Configuration.ParallelOptions,
y =>
{
for (int x = 0; x < pixels.Width; x++)
// TODO : move helper logic into the processor
QuantizedImage<TPixel> quantized = quantizer.Quantize(img, maxColors);
int palleteCount = quantized.Palette.Length - 1;
using (PixelAccessor<TPixel> pixels = new PixelAccessor<TPixel>(quantized.Width, quantized.Height))
{
Parallel.For(
0,
pixels.Height,
img.Configuration.ParallelOptions,
y =>
{
int i = x + (y * pixels.Width);
TPixel color = quantized.Palette[Math.Min(palleteCount, quantized.Pixels[i])];
pixels[x, y] = color;
}
});
for (int x = 0; x < pixels.Width; x++)
{
int i = x + (y * pixels.Width);
TPixel color = quantized.Palette[Math.Min(palleteCount, quantized.Pixels[i])];
pixels[x, y] = color;
}
});
source.SwapPixelsBuffers(pixels);
return source;
}
img.SwapPixelsBuffers(pixels);
}
});
}
}
}

4
tests/ImageSharp.Benchmarks/Drawing/DrawBeziers.cs

@ -47,7 +47,7 @@ namespace ImageSharp.Benchmarks
{
using (Image<Rgba32> image = new Image<Rgba32>(800, 800))
{
image.DrawBeziers(
image.Mutate(x => x.DrawBeziers(
Rgba32.HotPink,
10,
new SixLabors.Primitives.PointF[] {
@ -55,7 +55,7 @@ namespace ImageSharp.Benchmarks
new Vector2(30, 10),
new Vector2(240, 30),
new Vector2(300, 500)
});
}));
using (MemoryStream ms = new MemoryStream())
{

4
tests/ImageSharp.Benchmarks/Drawing/DrawLines.cs

@ -45,14 +45,14 @@ namespace ImageSharp.Benchmarks
{
using (Image<Rgba32> image = new Image<Rgba32>(800, 800))
{
image.DrawLines(
image.Mutate(x => x.DrawLines(
Rgba32.HotPink,
10,
new SixLabors.Primitives.PointF[] {
new Vector2(10, 10),
new Vector2(550, 50),
new Vector2(200, 400)
});
}));
using (MemoryStream ms = new MemoryStream())
{

4
tests/ImageSharp.Benchmarks/Drawing/DrawPolygon.cs

@ -47,14 +47,14 @@ namespace ImageSharp.Benchmarks
{
using (Image<Rgba32> image = new Image<Rgba32>(800, 800))
{
image.DrawPolygon(
image.Mutate(x => x.DrawPolygon(
Rgba32.HotPink,
10,
new SixLabors.Primitives.PointF[] {
new Vector2(10, 10),
new Vector2(550, 50),
new Vector2(200, 400)
});
}));
using (MemoryStream ms = new MemoryStream())
{

8
tests/ImageSharp.Benchmarks/Drawing/FillPolygon.cs

@ -55,13 +55,13 @@ namespace ImageSharp.Benchmarks
{
using (Image<Rgba32> image = new Image<Rgba32>(800, 800))
{
image.FillPolygon(
image.Mutate(x => x.FillPolygon(
Rgba32.HotPink,
new SixLabors.Primitives.PointF[] {
new Vector2(10, 10),
new Vector2(550, 50),
new Vector2(200, 400)
});
}));
using (MemoryStream ms = new MemoryStream())
{
@ -75,9 +75,9 @@ namespace ImageSharp.Benchmarks
{
using (Image<Rgba32> image = new Image<Rgba32>(800, 800))
{
image.Fill(
image.Mutate(x => x.Fill(
Rgba32.HotPink,
this.shape);
this.shape));
using (MemoryStream ms = new MemoryStream())
{

6
tests/ImageSharp.Benchmarks/Drawing/FillRectangle.cs

@ -39,7 +39,7 @@ namespace ImageSharp.Benchmarks
{
using (Image<Rgba32> image = new Image<Rgba32>(800, 800))
{
image.Fill(Rgba32.HotPink, new CoreRectangle(10, 10, 190, 140));
image.Mutate(x => x.Fill(Rgba32.HotPink, new CoreRectangle(10, 10, 190, 140)));
return new CoreSize(image.Width, image.Height);
}
@ -50,13 +50,13 @@ namespace ImageSharp.Benchmarks
{
using (Image<Rgba32> image = new Image<Rgba32>(800, 800))
{
image.FillPolygon(
image.Mutate(x => x.FillPolygon(
Rgba32.HotPink,
new SixLabors.Primitives.PointF[] {
new Vector2(10, 10),
new Vector2(200, 10),
new Vector2(200, 150),
new Vector2(10, 150) });
new Vector2(10, 150) }));
return new CoreSize(image.Width, image.Height);
}

2
tests/ImageSharp.Benchmarks/Drawing/FillWithPattern.cs

@ -40,7 +40,7 @@ namespace ImageSharp.Benchmarks
{
using (Image<Rgba32> image = new Image<Rgba32>(800, 800))
{
image.Fill(CoreBrushes.BackwardDiagonal(Rgba32.HotPink));
image.Mutate(x => x.Fill(CoreBrushes.BackwardDiagonal(Rgba32.HotPink)));
using (MemoryStream ms = new MemoryStream())
{

2
tests/ImageSharp.Benchmarks/Samplers/Crop.cs

@ -41,7 +41,7 @@ namespace ImageSharp.Benchmarks
{
using (Image<Rgba32> image = new Image<Rgba32>(800, 800))
{
image.Crop(100, 100);
image.Mutate(x => x.Crop(100, 100));
return new CoreSize(image.Width, image.Height);
}
}

22
tests/ImageSharp.Benchmarks/Samplers/DetectEdges.cs

@ -38,17 +38,17 @@ namespace ImageSharp.Benchmarks
[Benchmark(Description = "ImageSharp DetectEdges")]
public void ImageProcessorCoreDetectEdges()
{
this.image.DetectEdges(EdgeDetection.Kayyali);
this.image.DetectEdges(EdgeDetection.Kayyali);
this.image.DetectEdges(EdgeDetection.Kirsch);
this.image.DetectEdges(EdgeDetection.Lapacian3X3);
this.image.DetectEdges(EdgeDetection.Lapacian5X5);
this.image.DetectEdges(EdgeDetection.LaplacianOfGaussian);
this.image.DetectEdges(EdgeDetection.Prewitt);
this.image.DetectEdges(EdgeDetection.RobertsCross);
this.image.DetectEdges(EdgeDetection.Robinson);
this.image.DetectEdges(EdgeDetection.Scharr);
this.image.DetectEdges(EdgeDetection.Sobel);
this.image.Mutate(x => x.DetectEdges(EdgeDetection.Kayyali));
this.image.Mutate(x => x.DetectEdges(EdgeDetection.Kayyali));
this.image.Mutate(x => x.DetectEdges(EdgeDetection.Kirsch));
this.image.Mutate(x => x.DetectEdges(EdgeDetection.Lapacian3X3));
this.image.Mutate(x => x.DetectEdges(EdgeDetection.Lapacian5X5));
this.image.Mutate(x => x.DetectEdges(EdgeDetection.LaplacianOfGaussian));
this.image.Mutate(x => x.DetectEdges(EdgeDetection.Prewitt));
this.image.Mutate(x => x.DetectEdges(EdgeDetection.RobertsCross));
this.image.Mutate(x => x.DetectEdges(EdgeDetection.Robinson));
this.image.Mutate(x => x.DetectEdges(EdgeDetection.Scharr));
this.image.Mutate(x => x.DetectEdges(EdgeDetection.Sobel));
}
}
}

2
tests/ImageSharp.Benchmarks/Samplers/Glow.cs

@ -26,7 +26,7 @@ namespace ImageSharp.Benchmarks
[GlobalSetup]
public void Setup()
{
this.bulk = new GlowProcessor<Rgba32>(NamedColors<Rgba32>.Beige, GraphicsOptions.Default) { Radius = 800 * .5f, };
this.bulk = new GlowProcessor<Rgba32>(NamedColors<Rgba32>.Beige, 800 * .5f, GraphicsOptions.Default);
this.parallel = new GlowProcessorParallel<Rgba32>(NamedColors<Rgba32>.Beige) { Radius = 800 * .5f, };
}

2
tests/ImageSharp.Benchmarks/Samplers/Resize.cs

@ -41,7 +41,7 @@ namespace ImageSharp.Benchmarks
{
using (Image<Rgba32> image = new Image<Rgba32>(2000, 2000))
{
image.Resize(400, 400);
image.Mutate(x => x.Resize(400, 400));
return new CoreSize(image.Width, image.Height);
}
}

12
tests/ImageSharp.Tests/Drawing/BeziersTests.cs

@ -24,15 +24,15 @@ namespace ImageSharp.Tests.Drawing
string path = this.CreateOutputDirectory("Drawing", "BezierLine");
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image.BackgroundColor(Rgba32.Blue)
image.Mutate(x => x.BackgroundColor(Rgba32.Blue)
.DrawBeziers(Rgba32.HotPink, 5,
new SixLabors.Primitives.PointF[] {
new Vector2(10, 400),
new Vector2(30, 10),
new Vector2(240, 30),
new Vector2(300, 400)
})
.Save($"{path}/Simple.png");
}));
image.Save($"{path}/Simple.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
@ -63,7 +63,7 @@ namespace ImageSharp.Tests.Drawing
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image.BackgroundColor(Rgba32.Blue)
image.Mutate(x => x.BackgroundColor(Rgba32.Blue)
.DrawBeziers(color,
10,
new SixLabors.Primitives.PointF[]{
@ -71,8 +71,8 @@ namespace ImageSharp.Tests.Drawing
new Vector2(30, 10),
new Vector2(240, 30),
new Vector2(300, 400)
})
.Save($"{path}/Opacity.png");
}));
image.Save($"{path}/Opacity.png");
//shift background color towards forground color by the opacity amount
Rgba32 mergedColor = new Rgba32(Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));

42
tests/ImageSharp.Tests/Drawing/BlendedShapes.cs

@ -27,11 +27,12 @@ namespace ImageSharp.Tests.Drawing
{
var scaleX = (img.Width / 100);
var scaleY = (img.Height / 100);
img.Fill(NamedColors<TPixel>.DarkBlue, new Rectangle(0 * scaleX, 40 * scaleY, 100 * scaleX, 20 * scaleY));
img.Fill(NamedColors<TPixel>.HotPink, new Rectangle(20 * scaleX, 0 * scaleY, 30 * scaleX, 100 * scaleY), new ImageSharp.GraphicsOptions(true)
{
BlenderMode = mode
});
img.Mutate(x=>x
.Fill(NamedColors<TPixel>.DarkBlue, new Rectangle(0 * scaleX, 40 * scaleY, 100 * scaleX, 20 * scaleY))
.Fill(NamedColors<TPixel>.HotPink, new Rectangle(20 * scaleX, 0 * scaleY, 30 * scaleX, 100 * scaleY), new ImageSharp.GraphicsOptions(true)
{
BlenderMode = mode
}));
img.DebugSave(provider, new { mode });
}
}
@ -45,15 +46,15 @@ namespace ImageSharp.Tests.Drawing
{
var scaleX = (img.Width / 100);
var scaleY = (img.Height / 100);
img.Fill(NamedColors<TPixel>.DarkBlue, new Rectangle(0* scaleX, 40 * scaleY, 100 * scaleX, 20 * scaleY));
img.Fill(NamedColors<TPixel>.HotPink, new Rectangle(20 * scaleX, 0 * scaleY, 30 * scaleX, 100 * scaleY), new ImageSharp.GraphicsOptions(true)
img.Mutate(x=>x.Fill(NamedColors<TPixel>.DarkBlue, new Rectangle(0* scaleX, 40 * scaleY, 100 * scaleX, 20 * scaleY)));
img.Mutate(x => x.Fill(NamedColors<TPixel>.HotPink, new Rectangle(20 * scaleX, 0 * scaleY, 30 * scaleX, 100 * scaleY), new ImageSharp.GraphicsOptions(true)
{
BlenderMode = mode
});
img.Fill(NamedColors<TPixel>.Transparent, new SixLabors.Shapes.EllipsePolygon(40 * scaleX, 50 * scaleY, 50 * scaleX, 50 * scaleY), new ImageSharp.GraphicsOptions(true)
}));
img.Mutate(x => x.Fill(NamedColors<TPixel>.Transparent, new SixLabors.Shapes.EllipsePolygon(40 * scaleX, 50 * scaleY, 50 * scaleX, 50 * scaleY), new ImageSharp.GraphicsOptions(true)
{
BlenderMode = mode
});
}));
img.DebugSave(provider, new { mode });
}
}
@ -67,20 +68,20 @@ namespace ImageSharp.Tests.Drawing
{
var scaleX = (img.Width / 100);
var scaleY = (img.Height / 100);
img.Fill(NamedColors<TPixel>.DarkBlue, new Rectangle(0 * scaleX, 40, 100 * scaleX, 20* scaleY));
img.Fill(NamedColors<TPixel>.HotPink, new Rectangle(20 * scaleX, 0, 30 * scaleX, 100 * scaleY), new ImageSharp.GraphicsOptions(true)
img.Mutate(x=>x.Fill(NamedColors<TPixel>.DarkBlue, new Rectangle(0 * scaleX, 40, 100 * scaleX, 20* scaleY)));
img.Mutate(x => x.Fill(NamedColors<TPixel>.HotPink, new Rectangle(20 * scaleX, 0, 30 * scaleX, 100 * scaleY), new ImageSharp.GraphicsOptions(true)
{
BlenderMode = mode
});
}));
var c = NamedColors<TPixel>.Red.ToVector4();
c.W *= 0.5f;
TPixel pixel = default(TPixel);
pixel.PackFromVector4(c);
img.Fill(pixel, new SixLabors.Shapes.EllipsePolygon(40 * scaleX, 50 * scaleY, 50 * scaleX, 50 * scaleY), new ImageSharp.GraphicsOptions(true)
img.Mutate(x => x.Fill(pixel, new SixLabors.Shapes.EllipsePolygon(40 * scaleX, 50 * scaleY, 50 * scaleX, 50 * scaleY), new ImageSharp.GraphicsOptions(true)
{
BlenderMode = mode
});
}));
img.DebugSave(provider, new { mode });
}
}
@ -96,16 +97,11 @@ namespace ImageSharp.Tests.Drawing
{
var scaleX = (img.Width / 100);
var scaleY = (img.Height / 100);
img.Fill(NamedColors<TPixel>.DarkBlue, new Rectangle(0 * scaleX, 40* scaleY, 100 * scaleX, 20 * scaleY));
//img.Fill(NamedColors<TPixel>.HotPink, new Rectangle(20 * scaleX, 0 * scaleY, 30 * scaleX, 100 * scaleY), new ImageSharp.GraphicsOptions(true)
//{
// BlenderMode = mode
//});
img.Fill(NamedColors<TPixel>.Black, new SixLabors.Shapes.EllipsePolygon(40 * scaleX, 50 * scaleY, 50 * scaleX, 50 * scaleY), new ImageSharp.GraphicsOptions(true)
img.Mutate(x => x.Fill(NamedColors<TPixel>.DarkBlue, new Rectangle(0 * scaleX, 40* scaleY, 100 * scaleX, 20 * scaleY)));
img.Mutate(x => x.Fill(NamedColors<TPixel>.Black, new SixLabors.Shapes.EllipsePolygon(40 * scaleX, 50 * scaleY, 50 * scaleX, 50 * scaleY), new ImageSharp.GraphicsOptions(true)
{
BlenderMode = mode
});
}));
img.DebugSave(provider, new { mode });
}
}

4
tests/ImageSharp.Tests/Drawing/DrawImageTest.cs

@ -40,8 +40,8 @@ namespace ImageSharp.Tests
using (Image<TPixel> image = provider.GetImage())
using (Image<TPixel> blend = Image.Load<TPixel>(TestFile.Create(TestImages.Bmp.Car).Bytes))
{
image.DrawImage(blend, mode, .75f, new Size(image.Width / 2, image.Height / 2), new Point(image.Width / 4, image.Height / 4))
.DebugSave(provider, new { mode });
image.Mutate(x => x.DrawImage(blend, mode, .75f, new Size(image.Width / 2, image.Height / 2), new Point(image.Width / 4, image.Height / 4)));
image.DebugSave(provider, new { mode });
}
}
}

16
tests/ImageSharp.Tests/Drawing/DrawPathTests.cs

@ -34,10 +34,10 @@ namespace ImageSharp.Tests.Drawing
ShapePath p = new ShapePath(linerSegemnt, bazierSegment);
image
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Draw(Rgba32.HotPink, 5, p)
.Save($"{path}/Simple.png");
.Draw(Rgba32.HotPink, 5, p));
image.Save($"{path}/Simple.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
@ -74,10 +74,10 @@ namespace ImageSharp.Tests.Drawing
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Draw(color, 10, p)
.Save($"{path}/Opacity.png");
.Draw(color, 10, p));
image.Save($"{path}/Opacity.png");
//shift background color towards forground color by the opacity amount
Rgba32 mergedColor = new Rgba32(Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));
@ -101,12 +101,12 @@ namespace ImageSharp.Tests.Drawing
string path = this.CreateOutputDirectory("Drawing", "Path");
using (var image = new Image<Rgba32>(256, 256))
{
image.Fill(Rgba32.Black);
image.Mutate(x => x.Fill(Rgba32.Black));
var pen = Pens.Solid(Rgba32.White, 5f);
for (int i = 0; i < 300; i += 20)
{
image.DrawLines(pen, new SixLabors.Primitives.PointF[] { new Vector2(100, 2), new Vector2(-10, i) });
image.Mutate(x => x.DrawLines(pen, new SixLabors.Primitives.PointF[] { new Vector2(100, 2), new Vector2(-10, i) }));
}
image

7
tests/ImageSharp.Tests/Drawing/FillPatternTests.cs

@ -21,9 +21,9 @@ namespace ImageSharp.Tests.Drawing
string path = this.CreateOutputDirectory("Fill", "PatternBrush");
using (Image<Rgba32> image = new Image<Rgba32>(20, 20))
{
image
image.Mutate(x => x
.Fill(background)
.Fill(brush);
.Fill(brush));
image.Save($"{path}/{name}.png");
@ -51,7 +51,8 @@ namespace ImageSharp.Tests.Drawing
}
}
}
image.Resize(80, 80).Save($"{path}/{name}x4.png");
image.Mutate(x => x.Resize(80, 80));
image.Save($"{path}/{name}x4.png");
}
}

6
tests/ImageSharp.Tests/Drawing/FillRegionProcessorTests.cs

@ -71,18 +71,16 @@ namespace ImageSharp.Tests.Drawing
processor.Apply(img, bounds);
}
[Fact]
public void DrawOffCanvas()
{
using (var img = new Image<Rgba32>(10, 10))
{
img.DrawLines(new Pen<Rgba32>(Rgba32.Black, 10), new SixLabors.Primitives.PointF[] {
img.Mutate(x => x.DrawLines(new Pen<Rgba32>(Rgba32.Black, 10), new SixLabors.Primitives.PointF[] {
new Vector2(-10, 5),
new Vector2(20, 5),
});
}));
}
}
}

15
tests/ImageSharp.Tests/Drawing/FillSolidBrushTests.cs

@ -24,8 +24,9 @@ namespace ImageSharp.Tests.Drawing
string path = this.CreateOutputDirectory("Fill", "SolidBrush");
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image.Mutate(x => x
.Fill(Rgba32.HotPink));
image
.Fill(Rgba32.HotPink)
.Save($"{path}/DefaultBack.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
@ -43,10 +44,10 @@ namespace ImageSharp.Tests.Drawing
string path = this.CreateOutputDirectory("Fill", "SolidBrush");
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Fill(Rgba32.HotPink)
.Save($"{path}/Simple.png");
.Fill(Rgba32.HotPink));
image.Save($"{path}/Simple.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
@ -65,10 +66,10 @@ namespace ImageSharp.Tests.Drawing
{
Rgba32 color = new Rgba32(Rgba32.HotPink.R, Rgba32.HotPink.G, Rgba32.HotPink.B, 150);
image
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Fill(color)
.Save($"{path}/Opacity.png");
.Fill(color));
image.Save($"{path}/Opacity.png");
//shift background color towards forground color by the opacity amount
Rgba32 mergedColor = new Rgba32(Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));

30
tests/ImageSharp.Tests/Drawing/LineComplexPolygonTests.cs

@ -34,10 +34,10 @@ namespace ImageSharp.Tests.Drawing
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Draw(Rgba32.HotPink, 5, simplePath.Clip(hole1))
.Save($"{path}/Simple.png");
.Draw(Rgba32.HotPink, 5, simplePath.Clip(hole1)));
image.Save($"{path}/Simple.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
@ -81,10 +81,10 @@ namespace ImageSharp.Tests.Drawing
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Draw(Rgba32.HotPink, 5, simplePath.Clip(hole1))
.Save($"{path}/SimpleVanishHole.png");
.Draw(Rgba32.HotPink, 5, simplePath.Clip(hole1)));
image.Save($"{path}/SimpleVanishHole.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
@ -129,10 +129,10 @@ namespace ImageSharp.Tests.Drawing
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Draw(Rgba32.HotPink, 5, simplePath.Clip(hole1))
.Save($"{path}/SimpleOverlapping.png");
.Draw(Rgba32.HotPink, 5, simplePath.Clip(hole1)));
image.Save($"{path}/SimpleOverlapping.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
@ -172,10 +172,10 @@ namespace ImageSharp.Tests.Drawing
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Draw(Pens.Dash(Rgba32.HotPink, 5), simplePath.Clip(hole1))
.Save($"{path}/Dashed.png");
.Draw(Pens.Dash(Rgba32.HotPink, 5), simplePath.Clip(hole1)));
image.Save($"{path}/Dashed.png");
}
}
@ -197,10 +197,10 @@ namespace ImageSharp.Tests.Drawing
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Draw(color, 5, simplePath.Clip(hole1))
.Save($"{path}/Opacity.png");
.Draw(color, 5, simplePath.Clip(hole1)));
image.Save($"{path}/Opacity.png");
//shift background color towards forground color by the opacity amount
Rgba32 mergedColor = new Rgba32(Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));

88
tests/ImageSharp.Tests/Drawing/LineTests.cs

@ -23,15 +23,15 @@ namespace ImageSharp.Tests.Drawing
string path = this.CreateOutputDirectory("Drawing", "Lines");
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.DrawLines(Rgba32.HotPink, 5,
new SixLabors.Primitives.PointF[]{
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
})
.Save($"{path}/Simple.png");
}));
image.Save($"{path}/Simple.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
@ -50,7 +50,7 @@ namespace ImageSharp.Tests.Drawing
string path = this.CreateOutputDirectory("Drawing", "Lines");
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.DrawLines(Rgba32.HotPink, 5,
new SixLabors.Primitives.PointF[] {
@ -58,8 +58,8 @@ namespace ImageSharp.Tests.Drawing
new Vector2(200, 150),
new Vector2(50, 300)
},
new GraphicsOptions(false))
.Save($"{path}/Simple_noantialias.png");
new GraphicsOptions(false)));
image.Save($"{path}/Simple_noantialias.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
@ -78,17 +78,17 @@ namespace ImageSharp.Tests.Drawing
string path = this.CreateOutputDirectory("Drawing", "Lines");
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.DrawLines(Pens.Dash(Rgba32.HotPink, 5),
new SixLabors.Primitives.PointF[] {
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
})
.Save($"{path}/Dashed.png");
}
}));
image.Save($"{path}/Dashed.png");
}
}
[Fact]
public void ImageShouldBeOverlayedByPathDotted()
@ -96,17 +96,17 @@ namespace ImageSharp.Tests.Drawing
string path = this.CreateOutputDirectory("Drawing", "Lines");
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.DrawLines(Pens.Dot(Rgba32.HotPink, 5),
new SixLabors.Primitives.PointF[] {
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
})
.Save($"{path}/Dot.png");
}
}));
image.Save($"{path}/Dot.png");
}
}
[Fact]
public void ImageShouldBeOverlayedByPathDashDot()
@ -114,17 +114,17 @@ namespace ImageSharp.Tests.Drawing
string path = this.CreateOutputDirectory("Drawing", "Lines");
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.DrawLines(Pens.DashDot(Rgba32.HotPink, 5),
new SixLabors.Primitives.PointF[] {
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
})
.Save($"{path}/DashDot.png");
}
}));
image.Save($"{path}/DashDot.png");
}
}
[Fact]
public void ImageShouldBeOverlayedByPathDashDotDot()
@ -132,15 +132,15 @@ namespace ImageSharp.Tests.Drawing
string path = this.CreateOutputDirectory("Drawing", "Lines");
Image<Rgba32> image = new Image<Rgba32>(500, 500);
image
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.DrawLines(Pens.DashDotDot(Rgba32.HotPink, 5), new SixLabors.Primitives.PointF[] {
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
})
.Save($"{path}/DashDotDot.png");
}
}));
image.Save($"{path}/DashDotDot.png");
}
[Fact]
public void ImageShouldBeOverlayedPathWithOpacity()
@ -151,27 +151,27 @@ namespace ImageSharp.Tests.Drawing
Image<Rgba32> image = new Image<Rgba32>(500, 500);
image
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.DrawLines(color, 10, new SixLabors.Primitives.PointF[] {
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
})
.Save($"{path}/Opacity.png");
}));
image.Save($"{path}/Opacity.png");
//shift background color towards forground color by the opacity amount
Rgba32 mergedColor = new Rgba32(Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));
//shift background color towards forground color by the opacity amount
Rgba32 mergedColor = new Rgba32(Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(mergedColor, sourcePixels[11, 11]);
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(mergedColor, sourcePixels[11, 11]);
Assert.Equal(mergedColor, sourcePixels[199, 149]);
Assert.Equal(mergedColor, sourcePixels[199, 149]);
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
}
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
}
}
[Fact]
public void ImageShouldBeOverlayedByPathOutline()
@ -180,27 +180,27 @@ namespace ImageSharp.Tests.Drawing
Image<Rgba32> image = new Image<Rgba32>(500, 500);
image
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.DrawLines(Rgba32.HotPink, 10, new SixLabors.Primitives.PointF[] {
new Vector2(10, 10),
new Vector2(200, 10),
new Vector2(200, 150),
new Vector2(10, 150)
})
.Save($"{path}/Rectangle.png");
}));
image.Save($"{path}/Rectangle.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(Rgba32.HotPink, sourcePixels[11, 11]);
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
Assert.Equal(Rgba32.HotPink, sourcePixels[11, 11]);
Assert.Equal(Rgba32.HotPink, sourcePixels[198, 10]);
Assert.Equal(Rgba32.HotPink, sourcePixels[198, 10]);
Assert.Equal(Rgba32.Blue, sourcePixels[10, 50]);
Assert.Equal(Rgba32.Blue, sourcePixels[10, 50]);
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
}
Assert.Equal(Rgba32.Blue, sourcePixels[50, 50]);
}
}
}
}

8
tests/ImageSharp.Tests/Drawing/Paths/FillPath.cs

@ -37,7 +37,7 @@ namespace ImageSharp.Tests.Drawing.Paths
[Fact]
public void CorrectlySetsBrushAndPath()
{
img.Fill(brush, path);
img.Mutate(x => x.Fill(brush, path));
Assert.NotEmpty(img.ProcessorApplications);
FillRegionProcessor<Rgba32> processor = Assert.IsType<FillRegionProcessor<Rgba32>>(img.ProcessorApplications[0].processor);
@ -56,7 +56,7 @@ namespace ImageSharp.Tests.Drawing.Paths
[Fact]
public void CorrectlySetsBrushPathOptions()
{
img.Fill(brush, path, noneDefault);
img.Mutate(x => x.Fill(brush, path, noneDefault));
Assert.NotEmpty(img.ProcessorApplications);
FillRegionProcessor<Rgba32> processor = Assert.IsType<FillRegionProcessor<Rgba32>>(img.ProcessorApplications[0].processor);
@ -73,7 +73,7 @@ namespace ImageSharp.Tests.Drawing.Paths
[Fact]
public void CorrectlySetsColorAndPath()
{
img.Fill(color, path);
img.Mutate(x => x.Fill(color, path));
Assert.NotEmpty(img.ProcessorApplications);
FillRegionProcessor<Rgba32> processor = Assert.IsType<FillRegionProcessor<Rgba32>>(img.ProcessorApplications[0].processor);
@ -91,7 +91,7 @@ namespace ImageSharp.Tests.Drawing.Paths
[Fact]
public void CorrectlySetsColorPathAndOptions()
{
img.Fill(color, path, noneDefault);
img.Mutate(x => x.Fill(color, path, noneDefault));
Assert.NotEmpty(img.ProcessorApplications);
FillRegionProcessor<Rgba32> processor = Assert.IsType<FillRegionProcessor<Rgba32>>(img.ProcessorApplications[0].processor);

8
tests/ImageSharp.Tests/Drawing/Paths/FillPathCollection.cs

@ -47,7 +47,7 @@ namespace ImageSharp.Tests.Drawing.Paths
[Fact]
public void CorrectlySetsBrushAndPath()
{
img.Fill(brush, pathCollection);
img.Mutate(x => x.Fill(brush, pathCollection));
Assert.Equal(2, img.ProcessorApplications.Count);
for (var i = 0; i < 2; i++)
@ -69,7 +69,7 @@ namespace ImageSharp.Tests.Drawing.Paths
[Fact]
public void CorrectlySetsBrushPathOptions()
{
img.Fill(brush, pathCollection, noneDefault);
img.Mutate(x => x.Fill(brush, pathCollection, noneDefault));
Assert.Equal(2, img.ProcessorApplications.Count);
for (var i = 0; i < 2; i++)
@ -89,7 +89,7 @@ namespace ImageSharp.Tests.Drawing.Paths
[Fact]
public void CorrectlySetsColorAndPath()
{
img.Fill(color, pathCollection);
img.Mutate(x => x.Fill(color, pathCollection));
Assert.Equal(2, img.ProcessorApplications.Count);
for (var i = 0; i < 2; i++)
@ -110,7 +110,7 @@ namespace ImageSharp.Tests.Drawing.Paths
[Fact]
public void CorrectlySetsColorPathAndOptions()
{
img.Fill(color, pathCollection, noneDefault);
img.Mutate(x => x.Fill(color, pathCollection, noneDefault));
Assert.Equal(2, img.ProcessorApplications.Count);
for (var i = 0; i < 2; i++)

8
tests/ImageSharp.Tests/Drawing/Paths/FillPolygon.cs

@ -37,7 +37,7 @@ namespace ImageSharp.Tests.Drawing.Paths
[Fact]
public void CorrectlySetsBrushAndPath()
{
img.FillPolygon(brush, path);
img.Mutate(x => x.FillPolygon(brush, path));
Assert.NotEmpty(img.ProcessorApplications);
FillRegionProcessor<Rgba32> processor = Assert.IsType<FillRegionProcessor<Rgba32>>(img.ProcessorApplications[0].processor);
@ -54,7 +54,7 @@ namespace ImageSharp.Tests.Drawing.Paths
[Fact]
public void CorrectlySetsBrushPathAndOptions()
{
img.FillPolygon(brush, path, noneDefault);
img.Mutate(x => x.FillPolygon(brush, path, noneDefault));
Assert.NotEmpty(img.ProcessorApplications);
FillRegionProcessor<Rgba32> processor = Assert.IsType<FillRegionProcessor<Rgba32>>(img.ProcessorApplications[0].processor);
@ -71,7 +71,7 @@ namespace ImageSharp.Tests.Drawing.Paths
[Fact]
public void CorrectlySetsColorAndPath()
{
img.FillPolygon(color, path);
img.Mutate(x => x.FillPolygon(color, path));
Assert.NotEmpty(img.ProcessorApplications);
FillRegionProcessor<Rgba32> processor = Assert.IsType<FillRegionProcessor<Rgba32>>(img.ProcessorApplications[0].processor);
@ -89,7 +89,7 @@ namespace ImageSharp.Tests.Drawing.Paths
[Fact]
public void CorrectlySetsColorPathAndOptions()
{
img.FillPolygon(color, path, noneDefault);
img.Mutate(x => x.FillPolygon(color, path, noneDefault));
Assert.NotEmpty(img.ProcessorApplications);
FillRegionProcessor<Rgba32> processor = Assert.IsType<FillRegionProcessor<Rgba32>>(img.ProcessorApplications[0].processor);

8
tests/ImageSharp.Tests/Drawing/Paths/FillRectangle.cs

@ -32,7 +32,7 @@ namespace ImageSharp.Tests.Drawing.Paths
[Fact]
public void CorrectlySetsBrushAndRectangle()
{
img.Fill(brush, rectangle);
img.Mutate(x => x.Fill(brush, rectangle));
Assert.NotEmpty(img.ProcessorApplications);
FillRegionProcessor<Rgba32> processor = Assert.IsType<FillRegionProcessor<Rgba32>>(img.ProcessorApplications[0].processor);
@ -52,7 +52,7 @@ namespace ImageSharp.Tests.Drawing.Paths
[Fact]
public void CorrectlySetsBrushRectangleAndOptions()
{
img.Fill(brush, rectangle, noneDefault);
img.Mutate(x => x.Fill(brush, rectangle, noneDefault));
Assert.NotEmpty(img.ProcessorApplications);
FillRegionProcessor<Rgba32> processor = Assert.IsType<FillRegionProcessor<Rgba32>>(img.ProcessorApplications[0].processor);
@ -72,7 +72,7 @@ namespace ImageSharp.Tests.Drawing.Paths
[Fact]
public void CorrectlySetsColorAndRectangle()
{
img.Fill(color, rectangle);
img.Mutate(x => x.Fill(color, rectangle));
Assert.NotEmpty(img.ProcessorApplications);
FillRegionProcessor<Rgba32> processor = Assert.IsType<FillRegionProcessor<Rgba32>>(img.ProcessorApplications[0].processor);
@ -93,7 +93,7 @@ namespace ImageSharp.Tests.Drawing.Paths
[Fact]
public void CorrectlySetsColorRectangleAndOptions()
{
img.Fill(color, rectangle, noneDefault);
img.Mutate(x => x.Fill(color, rectangle, noneDefault));
Assert.NotEmpty(img.ProcessorApplications);
FillRegionProcessor<Rgba32> processor = Assert.IsType<FillRegionProcessor<Rgba32>>(img.ProcessorApplications[0].processor);

28
tests/ImageSharp.Tests/Drawing/PolygonTests.cs

@ -25,15 +25,15 @@ namespace ImageSharp.Tests.Drawing
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image
.BackgroundColor(Rgba32.Blue)
.DrawPolygon(Rgba32.HotPink, 5,
new SixLabors.Primitives.PointF[] {
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.DrawPolygon(Rgba32.HotPink, 5,
new SixLabors.Primitives.PointF[] {
new Vector2(10, 10),
new Vector2(200, 150),
new Vector2(50, 300)
})
.Save($"{path}/Simple.png");
}));
image.Save($"{path}/Simple.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
@ -62,10 +62,10 @@ namespace ImageSharp.Tests.Drawing
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image
.BackgroundColor(Rgba32.Blue)
.DrawPolygon(color, 10, simplePath)
.Save($"{path}/Opacity.png");
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.DrawPolygon(color, 10, simplePath));
image.Save($"{path}/Opacity.png");
//shift background color towards forground color by the opacity amount
Rgba32 mergedColor = new Rgba32(Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));
@ -90,10 +90,10 @@ namespace ImageSharp.Tests.Drawing
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image
.BackgroundColor(Rgba32.Blue)
.Draw(Rgba32.HotPink, 10, new Rectangle(10, 10, 190, 140))
.Save($"{path}/Rectangle.png");
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Draw(Rgba32.HotPink, 10, new Rectangle(10, 10, 190, 140)));
image.Save($"{path}/Rectangle.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{

8
tests/ImageSharp.Tests/Drawing/RecolorImageTest.cs

@ -27,8 +27,8 @@ namespace ImageSharp.Tests
{
using (Image<Rgba32> image = file.CreateImage())
{
image.Fill(brush)
.Save($"{path}/{file.FileName}");
image.Mutate(x => x.Fill(brush));
image.Save($"{path}/{file.FileName}");
}
}
}
@ -45,8 +45,8 @@ namespace ImageSharp.Tests
using (Image<Rgba32> image = file.CreateImage())
{
int imageHeight = image.Height;
image.Fill(brush, new Rectangle(0, imageHeight / 2 - imageHeight / 4, image.Width, imageHeight / 2))
.Save($"{path}/Shaped_{file.FileName}");
image.Mutate(x => x.Fill(brush, new Rectangle(0, imageHeight / 2 - imageHeight / 4, image.Width, imageHeight / 2)));
image.Save($"{path}/Shaped_{file.FileName}");
}
}
}

16
tests/ImageSharp.Tests/Drawing/SolidBezierTests.cs

@ -28,10 +28,10 @@ namespace ImageSharp.Tests.Drawing
};
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image
.BackgroundColor(Rgba32.Blue)
.Fill(Rgba32.HotPink, new Polygon(new CubicBezierLineSegment(simplePath)))
.Save($"{path}/Simple.png");
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Fill(Rgba32.HotPink, new Polygon(new CubicBezierLineSegment(simplePath))));
image.Save($"{path}/Simple.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
@ -60,10 +60,10 @@ namespace ImageSharp.Tests.Drawing
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image
.BackgroundColor(Rgba32.Blue)
.Fill(color, new Polygon(new CubicBezierLineSegment(simplePath)))
.Save($"{path}/Opacity.png");
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Fill(color, new Polygon(new CubicBezierLineSegment(simplePath))));
image.Save($"{path}/Opacity.png");
//shift background color towards forground color by the opacity amount
Rgba32 mergedColor = new Rgba32(Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));

18
tests/ImageSharp.Tests/Drawing/SolidComplexPolygonTests.cs

@ -34,10 +34,10 @@ namespace ImageSharp.Tests.Drawing
// var clipped = new Rectangle(10, 10, 100, 100).Clip(new Rectangle(20, 0, 20, 20));
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Fill(Rgba32.HotPink, clipped)
.Save($"{path}/Simple.png");
.Fill(Rgba32.HotPink, clipped));
image.Save($"{path}/Simple.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
@ -66,10 +66,10 @@ namespace ImageSharp.Tests.Drawing
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Fill(Rgba32.HotPink, simplePath.Clip(hole1))
.Save($"{path}/SimpleOverlapping.png");
.Fill(Rgba32.HotPink, simplePath.Clip(hole1)));
image.Save($"{path}/SimpleOverlapping.png");
using (PixelAccessor<Rgba32> sourcePixels = image.Lock())
{
@ -98,10 +98,10 @@ namespace ImageSharp.Tests.Drawing
using (Image<Rgba32> image = new Image<Rgba32>(500, 500))
{
image
image.Mutate(x => x
.BackgroundColor(Rgba32.Blue)
.Fill(color, simplePath.Clip(hole1))
.Save($"{path}/Opacity.png");
.Fill(color, simplePath.Clip(hole1)));
image.Save($"{path}/Opacity.png");
//shift background color towards forground color by the opacity amount
Rgba32 mergedColor = new Rgba32(Vector4.Lerp(Rgba32.Blue.ToVector4(), Rgba32.HotPink.ToVector4(), 150f / 255f));

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save