// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // namespace ImageSharp.Processing.Processors { using System; using System.Threading.Tasks; /// /// Provides methods that allow the flipping of an image around its center point. /// /// The pixel format. public class FlipProcessor : ImageProcessor where TColor : struct, IPackedPixel, IEquatable { /// /// Initializes a new instance of the class. /// /// The used to perform flipping. public FlipProcessor(FlipType flipType) { this.FlipType = flipType; } /// /// Gets the used to perform flipping. /// public FlipType FlipType { get; } /// protected override void OnApply(ImageBase source, Rectangle sourceRectangle) { switch (this.FlipType) { // No default needed as we have already set the pixels. case FlipType.Vertical: this.FlipX(source); break; case FlipType.Horizontal: this.FlipY(source); break; } } /// /// Swaps the image at the X-axis, which goes horizontally through the middle /// at half the height of the image. /// /// The source image to apply the process to. private void FlipX(ImageBase source) { int width = source.Width; int height = source.Height; int halfHeight = (int)Math.Ceiling(source.Height * .5F); using (PixelAccessor targetPixels = new PixelAccessor(width, height)) { using (PixelAccessor sourcePixels = source.Lock()) { Parallel.For( 0, halfHeight, this.ParallelOptions, y => { for (int x = 0; x < width; x++) { int newY = height - y - 1; targetPixels[x, y] = sourcePixels[x, newY]; targetPixels[x, newY] = sourcePixels[x, y]; } }); } source.SwapPixelsBuffers(targetPixels); } } /// /// Swaps the image at the Y-axis, which goes vertically through the middle /// at half of the width of the image. /// /// The source image to apply the process to. private void FlipY(ImageBase source) { int width = source.Width; int height = source.Height; int halfWidth = (int)Math.Ceiling(width * .5F); using (PixelAccessor targetPixels = new PixelAccessor(width, height)) { using (PixelAccessor sourcePixels = source.Lock()) { Parallel.For( 0, height, this.ParallelOptions, y => { for (int x = 0; x < halfWidth; x++) { int newX = width - x - 1; targetPixels[x, y] = sourcePixels[newX, y]; targetPixels[newX, y] = sourcePixels[x, y]; } }); } source.SwapPixelsBuffers(targetPixels); } } } }