#![deny(
clippy::all,
clippy::suspicious,
clippy::complexity,
clippy::perf,
clippy::style,
clippy::pedantic,
clippy::cargo,
clippy::nursery
)]
#![warn(clippy::unwrap_used)]
#![allow(clippy::multiple_crate_versions)]
use std::time::{Duration, Instant};
use image::DynamicImage;
use imageslapper::{
builders::ImageBuilder, geometry::rectangle::Rectangle, helpers,
io::images::load_image_with_qoi, rendering::draw::ImageWrapper, text,
};
use tracing::info;
fn remove_testing_outputs() -> Duration {
let start = Instant::now();
std::fs::remove_dir_all("testing-outputs").unwrap_or_else(|_| {
info!("No testing-outputs directory to remove");
});
start.elapsed()
}
fn read_image_metadata(image_path: &str) -> (u64, Duration) {
let start = Instant::now();
let size = std::fs::metadata(image_path)
.expect("Failed to read image size")
.len();
info!("{size} bytes, {} kb", size / 1024);
(size, start.elapsed())
}
fn create_output_directory() -> Duration {
let start = Instant::now();
std::fs::create_dir_all("testing-outputs").expect("Failed to create output directory");
start.elapsed()
}
#[must_use]
pub fn create_image_wrapper(image: DynamicImage) -> (ImageWrapper, std::time::Duration) {
let start = Instant::now();
let wrapper = ImageWrapper::new(image);
(wrapper, start.elapsed())
}
fn barcode_demo() -> Duration {
let start = Instant::now();
let content = "123456 jump!";
let image =
helpers::code128::from(content, 500, 500, 25).expect("Failed to build code128 barcode");
ImageWrapper::new(image).save_image("testing-outputs/Code128.png").expect("Failed to save barcode image");
start.elapsed()
}
fn coordinates_demo() -> Duration {
let start = Instant::now();
start.elapsed()
}
fn fields_demo() -> Duration {
let start = Instant::now();
start.elapsed()
}
fn inverted_multiline_demo() -> Duration {
let start = Instant::now();
start.elapsed()
}
fn qr_demo() -> Duration {
let start = Instant::now();
start.elapsed()
}
fn single_line_demo() -> Duration {
let start = Instant::now();
start.elapsed()
}
fn text_anchors_demo() -> Duration {
let start = Instant::now();
start.elapsed()
}
#[tokio::main]
async fn main() {
let start = Instant::now();
let filter = tracing_subscriber::EnvFilter::new("debug");
tracing_subscriber::fmt().with_env_filter(filter).init();
let time_remove_dir = remove_testing_outputs();
let image_path = "testing-inputs/image.avif";
let (image, time_load_image) = load_image_with_qoi(image_path);
let (_, time_read_metadata) = read_image_metadata(image_path);
let rectangle_height = image.height() * 4 / 10;
let rectangle_width = image.width();
let rectangle = Rectangle::new(0, 0, rectangle_width, rectangle_height);
let image = ImageBuilder::from_image(image)
.add_rectangle(rectangle)
.add_text(
text::helpers::simple_open_sans("Hello, world!", rectangle)
.expect("Failed to create text"),
)
.get_image();
let time_render_text_and_rectangle = start.elapsed();
let time_create_output_dir = create_output_directory();
ImageWrapper::new(image).save_image("testing-outputs/image.png").expect("Failed to save image");
let time_save_image = start.elapsed() - time_create_output_dir;
let time_barcode_demo = barcode_demo();
let time_coordinates_demo = coordinates_demo();
let time_fields_demo = fields_demo();
let time_inverted_multiline_demo = inverted_multiline_demo();
let time_qr_demo = qr_demo();
let time_single_line_demo = single_line_demo();
let time_text_anchors_demo = text_anchors_demo();
info!("Summary of elapsed times:");
info!("Removing directory: {:?}", time_remove_dir);
info!(
"Loading image: {:?}",
time_load_image.saturating_sub(time_remove_dir)
);
info!(
"Reading metadata: {:?}",
time_read_metadata.saturating_sub(time_load_image)
);
info!(
"Rendering text and rectangle: {:?}",
time_render_text_and_rectangle.saturating_sub(time_read_metadata)
);
info!(
"Saving image: {:?}",
time_save_image.saturating_sub(time_create_output_dir)
);
info!(
"Total time elapsed: {:?}",
time_remove_dir
+ time_load_image
+ time_read_metadata
+ time_render_text_and_rectangle
+ time_create_output_dir
+ time_save_image
);
info!("Demo timings:");
info!("Barcode demo: {:?}", time_barcode_demo);
info!("Coordinates demo: {:?}", time_coordinates_demo);
info!("Fields demo: {:?}", time_fields_demo);
info!(
"Inverted multiline demo: {:?}",
time_inverted_multiline_demo
);
info!("QR demo: {:?}", time_qr_demo);
info!("Single line demo: {:?}", time_single_line_demo);
info!("Text anchors demo: {:?}", time_text_anchors_demo);
}