Just as in the example where we were resizing an image, here too we use the image crate.
Create the crate
Let's create a new crate called crop-image
and add the image
crate as a dependency:
cargo new crop-image
cd crop-image
cargo add image
Or manually update Cargo.toml
:
[dependencies]
image = "0.24"
How to use this command?
cargo run some_image.jpg name_of_the_cropped_image.png 200 200 100 100
Running cargo run
will show you the usage message that will include the expected parameters.
INFILE OUTFILE X Y WIDTH HEIGHT
From the original image we will retain the image that is located at the (x,y) of the original image, using the top left corner as (0, 0) and has a width and hight as provided on the command line. So if we have an image that is 800 pixels wide and 600 high then
-
0 0 400 300
will create an image from the top left quarter of the original images. -
400 300 400 300
will create an image from the bottom right quarter of the original image. -
200 150 400 300
will create an image from the middle of the original image. -
0 0 800 100
will create an image from the top 100 pixels of the original image.
About the code
We have a function called get_args
that will get the arguments from the command line and would print a usage-message if the user has not supplied
the correct number of arguments.
examples/crop-image/src/main.rs
fn main() {
let (infile, outfile, x, y, width, height) = get_args();
let img = image::open(infile).unwrap();
println!("Original width={}, height={}", img.width(), img.height());
println!(
"Cropped to: ({},{}) width={}, height={}",
x, y, width, height
);
let cropped = img.crop_imm(x, y, width, height);
cropped.save(outfile).unwrap();
}
fn get_args() -> (String, String, u32, u32, u32, u32) {
let args = std::env::args().collect::<Vec<String>>();
if args.len() != 7 {
eprintln!("Usage: {} INFILE OUTFILE X Y WIDTH HEIGHT", args[0]);
std::process::exit(1);
}
(
args[1].to_owned(),
args[2].to_owned(),
args[3].parse().unwrap(),
args[4].parse().unwrap(),
args[5].parse().unwrap(),
args[6].parse().unwrap(),
)
}
The image::open function will read the image into memory,
crop_imm will return a cropped version of the image.
That is "crop immutable". There is also a function called crop,
but that required the img
to be mutable.
The save method will save the new image in format appropriate to the file extension we gave to it.
Conclusion
It is quite easy to crop an image. Let's see what else can we do easily.