@@ -18,13 +18,27 @@ public class ImageBrush : IBrush
1818 /// </summary>
1919 private readonly Image image ;
2020
21+ private readonly RectangleF ? region ;
22+
2123 /// <summary>
2224 /// Initializes a new instance of the <see cref="ImageBrush"/> class.
2325 /// </summary>
2426 /// <param name="image">The image.</param>
2527 public ImageBrush ( Image image )
28+ => this . image = image ;
29+
30+ /// <summary>
31+ /// Initializes a new instance of the <see cref="ImageBrush"/> class.
32+ /// </summary>
33+ /// <param name="image">The image.</param>
34+ /// <param name="region">
35+ /// The region of interest.
36+ /// This overrides any region used to intitialize the brush applicator.
37+ /// </param>
38+ internal ImageBrush ( Image image , RectangleF region )
2639 {
2740 this . image = image ;
41+ this . region = region ;
2842 }
2943
3044 /// <inheritdoc />
@@ -35,19 +49,22 @@ public BrushApplicator<TPixel> CreateApplicator<TPixel>(
3549 RectangleF region )
3650 where TPixel : unmanaged, IPixel < TPixel >
3751 {
52+ RectangleF interest = this . region ?? region ;
53+
3854 if ( this . image is Image < TPixel > specificImage )
3955 {
40- return new ImageBrushApplicator < TPixel > ( configuration , options , source , specificImage , region , false ) ;
56+ return new ImageBrushApplicator < TPixel > ( configuration , options , source , specificImage , interest , false ) ;
4157 }
4258
4359 specificImage = this . image . CloneAs < TPixel > ( ) ;
4460
45- return new ImageBrushApplicator < TPixel > ( configuration , options , source , specificImage , region , true ) ;
61+ return new ImageBrushApplicator < TPixel > ( configuration , options , source , specificImage , interest , true ) ;
4662 }
4763
4864 /// <summary>
4965 /// The image brush applicator.
5066 /// </summary>
67+ /// <typeparam name="TPixel">The pixel format.</typeparam>
5168 private class ImageBrushApplicator < TPixel > : BrushApplicator < TPixel >
5269 where TPixel : unmanaged, IPixel < TPixel >
5370 {
@@ -139,32 +156,30 @@ public override void Apply(Span<float> scanline, int x, int y)
139156 {
140157 // Create a span for colors
141158 MemoryAllocator allocator = this . Configuration . MemoryAllocator ;
142- using ( IMemoryOwner < float > amountBuffer = allocator . Allocate < float > ( scanline . Length ) )
143- using ( IMemoryOwner < TPixel > overlay = allocator . Allocate < TPixel > ( scanline . Length ) )
159+ using IMemoryOwner < float > amountBuffer = allocator . Allocate < float > ( scanline . Length ) ;
160+ using IMemoryOwner < TPixel > overlay = allocator . Allocate < TPixel > ( scanline . Length ) ;
161+ Span < float > amountSpan = amountBuffer . Memory . Span ;
162+ Span < TPixel > overlaySpan = overlay . Memory . Span ;
163+
164+ int sourceY = ( y - this . offsetY ) % this . yLength ;
165+ int offsetX = x - this . offsetX ;
166+ Span < TPixel > sourceRow = this . sourceFrame . GetPixelRowSpan ( sourceY ) ;
167+
168+ for ( int i = 0 ; i < scanline . Length ; i ++ )
144169 {
145- Span < float > amountSpan = amountBuffer . Memory . Span ;
146- Span < TPixel > overlaySpan = overlay . Memory . Span ;
147-
148- int sourceY = ( y - this . offsetY ) % this . yLength ;
149- int offsetX = x - this . offsetX ;
150- Span < TPixel > sourceRow = this . sourceFrame . GetPixelRowSpan ( sourceY ) ;
151-
152- for ( int i = 0 ; i < scanline . Length ; i ++ )
153- {
154- amountSpan [ i ] = scanline [ i ] * this . Options . BlendPercentage ;
155-
156- int sourceX = ( i + offsetX ) % this . xLength ;
157- overlaySpan [ i ] = sourceRow [ sourceX ] ;
158- }
159-
160- Span < TPixel > destinationRow = this . Target . GetPixelRowSpan ( y ) . Slice ( x , scanline . Length ) ;
161- this . Blender . Blend (
162- this . Configuration ,
163- destinationRow ,
164- destinationRow ,
165- overlaySpan ,
166- amountSpan ) ;
170+ amountSpan [ i ] = scanline [ i ] * this . Options . BlendPercentage ;
171+
172+ int sourceX = ( i + offsetX ) % this . xLength ;
173+ overlaySpan [ i ] = sourceRow [ sourceX ] ;
167174 }
175+
176+ Span < TPixel > destinationRow = this . Target . GetPixelRowSpan ( y ) . Slice ( x , scanline . Length ) ;
177+ this . Blender . Blend (
178+ this . Configuration ,
179+ destinationRow ,
180+ destinationRow ,
181+ overlaySpan ,
182+ amountSpan ) ;
168183 }
169184 }
170185 }
0 commit comments