1
Fork 0
shimmeringmoon/src/image.rs

54 lines
1.8 KiB
Rust
Raw Normal View History

use image::{DynamicImage, GenericImage, GenericImageView};
use crate::bitmap::{Position, Rect};
fn unsigned_in_bounds(image: &DynamicImage, x: i32, y: i32) -> bool {
x >= 0 && y >= 0 && image.in_bounds(x as u32, y as u32)
}
/// Performs a horizontal shear operation, without performing anti-aliasing
pub fn xshear(image: &mut DynamicImage, rect: Rect, center: Position, shear: f32) {
let width = rect.width as i32;
for y in rect.y..rect.y + rect.height as i32 {
let skew = (shear * ((y - center.1) as f32)) as i32;
for i in rect.x..rect.x + width {
let x = if skew < 0 { i } else { rect.x + width - 1 - i };
if unsigned_in_bounds(image, x, y) {
let pixel = image.get_pixel(x as u32, y as u32);
if unsigned_in_bounds(image, x + skew, y) {
image.put_pixel((x + skew) as u32, y as u32, pixel);
};
};
}
}
}
/// Performs a horizontal shear operation, without performing anti-aliasing
pub fn yshear(image: &mut DynamicImage, rect: Rect, center: Position, shear: f32) {
let height = rect.height as i32;
for x in rect.x..rect.x + rect.height as i32 {
let skew = (shear * ((x - center.0) as f32)) as i32;
for i in rect.y..rect.y + height {
let y = if skew < 0 { i } else { rect.y + height - 1 - i };
if unsigned_in_bounds(image, x, y) {
let pixel = image.get_pixel(x as u32, y as u32);
if unsigned_in_bounds(image, x, y + skew) {
image.put_pixel(x as u32, (y + skew) as u32, pixel);
};
};
}
}
}
/// Performs a rotation as a series of three shear operations
/// Does not perform anti-aliasing.
pub fn rotate(image: &mut DynamicImage, rect: Rect, center: Position, angle: f32) {
let alpha = -f32::tan(angle);
let beta = f32::sin(angle);
xshear(image, rect, center, alpha);
yshear(image, rect, center, beta);
xshear(image, rect, center, alpha);
}