Skip to content

Commit

Permalink
Add functions to rotate by quarter turns (#669)
Browse files Browse the repository at this point in the history
  • Loading branch information
ripytide authored Jun 13, 2024
1 parent c799551 commit 75246e3
Showing 1 changed file with 140 additions and 0 deletions.
140 changes: 140 additions & 0 deletions src/geometric_transformations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,146 @@ where
warp(image, &projection, interpolation, default)
}

/// Rotates an image 90 degrees clockwise.
///
/// # Examples
/// ```
/// use imageproc::geometric_transformations::rotate90;
/// use imageproc::gray_image;
///
/// let image = gray_image!(
/// 1, 2, 0, 0;
/// 3, 4, 0, 0;
/// 0, 0, 0, 0;
/// 0, 0, 0, 0);
///
/// let rotated = rotate90(&image);
///
/// assert_eq!(rotated, gray_image!(
/// 0, 0, 3, 1;
/// 0, 0, 4, 2;
/// 0, 0, 0, 0;
/// 0, 0, 0, 0));
/// ```
pub fn rotate90<P>(image: &Image<P>) -> Image<P>
where
P: Pixel,
{
let (width, height) = image.dimensions();

let mut rotated = Image::new(height, width);

for y in 0..height {
for x in 0..width {
rotated.put_pixel(height - y - 1, x, *image.get_pixel(x, y));
}
}

rotated
}

/// Rotates an image 270 degrees clockwise.
///
/// # Examples
/// ```
/// use imageproc::geometric_transformations::rotate270;
/// use imageproc::gray_image;
///
/// let image = gray_image!(
/// 1, 2, 0, 0;
/// 3, 4, 0, 0;
/// 0, 0, 0, 0;
/// 0, 0, 0, 0);
///
/// let rotated = rotate270(&image);
///
/// assert_eq!(rotated, gray_image!(
/// 0, 0, 0, 0;
/// 0, 0, 0, 0;
/// 2, 4, 0, 0;
/// 1, 3, 0, 0));
/// ```
pub fn rotate270<P>(image: &Image<P>) -> Image<P>
where
P: Pixel,
{
let (width, height) = image.dimensions();

let mut rotated = Image::new(height, width);

for y in 0..height {
for x in 0..width {
rotated.put_pixel(y, width - x - 1, *image.get_pixel(x, y));
}
}

rotated
}

/// Rotates an image 180 degrees clockwise.
///
/// # Examples
/// ```
/// use imageproc::geometric_transformations::rotate180;
/// use imageproc::gray_image;
///
/// let image = gray_image!(
/// 1, 2, 0, 0;
/// 3, 4, 0, 0;
/// 0, 0, 0, 0;
/// 0, 0, 0, 0);
///
/// let rotated = rotate180(&image);
///
/// assert_eq!(rotated, gray_image!(
/// 0, 0, 0, 0;
/// 0, 0, 0, 0;
/// 0, 0, 4, 3;
/// 0, 0, 2, 1));
/// ```
pub fn rotate180<P>(image: &Image<P>) -> Image<P>
where
P: Pixel,
{
let mut out = image.clone();
rotate180_mut(&mut out);
out
}
#[doc=generate_mut_doc_comment!("rotate180")]
pub fn rotate180_mut<P>(image: &mut Image<P>)
where
P: Pixel,
{
let (width, height) = image.dimensions();

for y in 0..height / 2 {
for x in 0..width {
let x180 = width - x - 1;
let y180 = height - y - 1;

let p = *image.get_pixel(x, y);
let p180 = *image.get_pixel(x180, y180);

image.put_pixel(x, y, p180);
image.put_pixel(x180, y180, p);
}
}

if height % 2 != 0 {
let y_middle = height / 2;

for x in 0..width / 2 {
let x180 = width - x - 1;

let p = *image.get_pixel(x, y_middle);
let p180 = *image.get_pixel(x180, y_middle);

image.put_pixel(x, y_middle, p180);
image.put_pixel(x180, y_middle, p);
}
}
}

/// Translates the input image by t. Note that image coordinates increase from
/// top left to bottom right. Output pixels whose pre-image are not in the input
/// image are set to the boundary pixel in the input image nearest to their pre-image.
Expand Down

0 comments on commit 75246e3

Please sign in to comment.