| Crates.io | imx |
| lib.rs | imx |
| version | 0.1.20 |
| created_at | 2025-02-15 19:20:39.332462+00 |
| updated_at | 2025-03-31 12:26:17.734188+00 |
| description | A library for image processing and manipulation |
| homepage | https://github.com/rakki194/imx |
| repository | https://github.com/rakki194/imx |
| max_upload_size | |
| id | 1557034 |
| size | 11,596,746 |
A comprehensive Rust library for image processing, manipulation, and visualization.
Add the following to your Cargo.toml:
cargo add imx
This library uses the log crate for logging and outputs detailed information about processing steps.
Configure a logger (e.g., env_logger, simplelog) in your application:
// Example with env_logger
use env_logger::{Builder, Env};
fn main() {
// Initialize logger with INFO level by default
Builder::from_env(Env::default().default_filter_or("info"))
.init();
// Your code that uses imx...
}
remove_letterboxRemoves black borders (letterboxing) from an image by automatically detecting and cropping them.
async fn remove_letterbox(path: &Path) -> Result<()>
path - Path to the image fileResult<()> indicating success or failureremove_letterbox_with_thresholdSimilar to remove_letterbox but allows specifying a threshold value to detect borders.
async fn remove_letterbox_with_threshold(path: &Path, threshold: u8) -> Result<()>
path - Path to the image filethreshold - Threshold value (0-255) for detecting letterbox bordersremove_transparencyReplaces transparent pixels with black, opaque pixels.
async fn remove_transparency(path: &Path) -> Result<()>
path - Path to the image fileget_image_dimensionsRetrieves the width and height of an image.
fn get_image_dimensions(path: &Path) -> Result<(u32, u32)>
path - Path to the image file(width, height) as u32 valuesprocess_imageGeneric function to apply any async image processing operation to a file.
async fn process_image<F, Fut>(path: PathBuf, processor: F) -> Result<()>
where
F: FnOnce(PathBuf) -> Fut,
Fut: std::future::Future<Output = Result<()>>
path - Path to the image file to processprocessor - Async function that performs the actual image processingis_image_fileDetermines if a file is an image by checking both extension and file contents.
fn is_image_file(path: &Path) -> bool
path - Path to checkdetect_image_formatDetects image format from file contents using magic numbers.
fn detect_image_format(buffer: &[u8]) -> Option<DetectedImageFormat>
buffer - Byte buffer containing the file headerconvert_imageConverts an image from one format to another with format-specific options.
async fn convert_image(
input_path: &Path,
output_path: &Path,
options: Option<ImageFormatOptions>
) -> Result<()>
input_path - Path to the input imageoutput_path - Path where the converted image should be savedoptions - Optional format-specific conversion optionsimage crateconvert_images_batchConverts multiple images in a batch operation.
async fn convert_images_batch(
input_paths: &[PathBuf],
output_dir: &Path,
output_format: ImageFormat,
options: Option<ImageFormatOptions>
) -> Result<()>
input_paths - List of input image pathsoutput_dir - Directory where converted images should be savedoutput_format - Target format for conversionoptions - Optional format-specific conversion optionsdetect_format_from_extensionDetects image format from file extension.
fn detect_format_from_extension(path: &Path) -> Option<ImageFormat>
path - Path to check for formatSome(ImageFormat) if a supported format is detected, None otherwiseImageFormatOptionsStruct for configuring image format conversion options.
struct ImageFormatOptions {
quality: u8, // Quality value (1-100)
lossless: bool, // Whether to use lossless compression
extra_options: HashMap<String, String> // Format-specific options
}
ImageFormatOptions::default() - 85% quality, lossy compressionImageFormatOptions::jpeg() - 85% quality, lossy compressionImageFormatOptions::png() - 100% quality, lossless compressionImageFormatOptions::webp() - 85% quality, lossy compression.with_quality(quality: u8) - Set specific quality level.with_lossless(lossless: bool) - Toggle lossless compression.with_option(key: &str, value: &str) - Add format-specific optionis_jxl_fileChecks if a file is a JPEG XL image by examining its file extension.
fn is_jxl_file(path: &Path) -> bool
path - Path to the file to checkconvert_jxl_to_pngConverts a JPEG XL image to PNG format.
async fn convert_jxl_to_png(input_path: &Path, output_path: &Path) -> Result<()>
input_path - Path to the input JXL fileoutput_path - Path where the PNG file should be savedjxl-oxideprocess_jxl_fileProcesses a JXL file with an optional custom processor function.
async fn process_jxl_file<F, Fut>(
input_path: &Path,
processor: Option<F>
) -> Result<()>
where
F: FnOnce(PathBuf) -> Fut + Send,
Fut: std::future::Future<Output = Result<()>> + Send
input_path - Path to the JXL fileprocessor - Optional function to process the decoded PNGf32_to_i32Safely converts an f32 to i32, with proper rounding and range clamping.
fn f32_to_i32(x: f32) -> i32
x - The f32 value to converti32::MIN or i32::MAXi32_to_u32Safely converts an i32 to u32, clamping negative values to 0.
fn i32_to_u32(x: i32) -> u32
x - The i32 value to convertu32_to_i32Safely converts a u32 to i32, clamping values exceeding i32::MAX.
fn u32_to_i32(x: u32) -> i32
x - The u32 value to convertf32_to_u8Safely converts an f32 to u8, with proper rounding and range clamping.
fn f32_to_u8(x: f32) -> u8
x - The f32 value to converti32_to_f32_for_posConverts an i32 to f32, optimized for image positioning calculations.
fn i32_to_f32_for_pos(x: i32) -> f32
x - The i32 value to convertf32_to_u32Safely converts an f32 to u32, with proper rounding and range clamping.
fn f32_to_u32(x: f32) -> u32
x - The f32 value to convertcreate_plotCreates an image grid plot with optional row and column labels.
fn create_plot(config: &PlotConfig) -> Result<()>
config - Configuration for the plotPlotConfigConfiguration struct for creating image grid plots.
struct PlotConfig {
images: Vec<PathBuf>, // List of image file paths to include
output: PathBuf, // Output file path
rows: u32, // Number of rows in the grid
row_labels: Vec<String>, // Optional row labels
column_labels: Vec<String>, // Optional column labels
column_label_alignment: LabelAlignment, // How to align column labels
row_label_alignment: LabelAlignment, // How to align row labels
debug_mode: bool, // Whether to output debug visualization
top_padding: u32, // Space at the top for labels
left_padding: u32, // Space at the left for row labels
font_size: Option<f32>, // Optional custom font size for labels
}
top_padding: 40 pixelsleft_padding: 40 pixelscolumn_label_alignment: Centerrow_label_alignment: Centerdebug_mode: falsefont_size: None (use default font size)LabelAlignmentEnum for specifying label alignment in plots.
enum LabelAlignment {
Start, // Place labels at the left/top edge
Center, // Center labels (default)
End, // Place labels at the right/bottom edge
}
Center alignment for both row and column labelsLayoutRepresents the complete layout of a plot for rendering.
struct Layout {
elements: Vec<LayoutElement>,
total_width: u32,
total_height: u32,
}
new(width: u32, height: u32) - Creates a new empty layoutadd_element(element: LayoutElement) - Adds an element to the layoutrender_debug() - Renders a debug visualization of the layoutLayoutElementRepresents different types of elements in a layout.
enum LayoutElement {
Image { rect: LayoutRect, path: String },
RowLabel { rect: LayoutRect, text: String },
ColumnLabel { rect: LayoutRect, text: String },
Padding { rect: LayoutRect, description: String },
}
Image - An image to be displayed in the gridRowLabel - A label for a row of imagesColumnLabel - A label for a column of imagesPadding - Empty space in the layoutLayoutRectRepresents a rectangular region in the layout.
struct LayoutRect {
x: i32,
y: i32,
width: u32,
height: u32,
}
use std::path::Path;
use anyhow::Result;
use imx::{remove_letterbox, remove_transparency};
async fn process_images() -> Result<()> {
// Remove letterboxing from an image
let image_path = Path::new("input/movie_frame.jpg");
remove_letterbox(image_path).await?;
// Remove transparency from a PNG
let png_path = Path::new("input/logo.png");
remove_transparency(png_path).await?;
Ok(())
}
use std::path::{Path, PathBuf};
use anyhow::Result;
use imx::{convert_image, convert_images_batch, ImageFormatOptions};
use image::ImageFormat;
async fn convert_images_example() -> Result<()> {
// Convert a single image to WebP with custom quality
let input = Path::new("input/photo.jpg");
let output = Path::new("output/photo.webp");
let options = ImageFormatOptions::webp()
.with_quality(90)
.with_lossless(false);
convert_image(input, output, Some(options)).await?;
// Batch convert all JPEGs in a directory to PNG
let input_dir = Path::new("input");
let output_dir = Path::new("output/png");
// Collect input paths
let mut input_paths: Vec<PathBuf> = Vec::new();
for entry in std::fs::read_dir(input_dir)? {
let path = entry?.path();
if path.extension().map_or(false, |ext| ext == "jpg") {
input_paths.push(path);
}
}
// Convert all images to PNG with lossless compression
let png_options = ImageFormatOptions::png();
convert_images_batch(&input_paths, output_dir, ImageFormat::Png, Some(png_options)).await?;
Ok(())
}
use std::path::Path;
use anyhow::Result;
use imx::jxl::{convert_jxl_to_png, process_jxl_file};
async fn process_jxl_example() -> Result<()> {
// Simple conversion from JXL to PNG
let jxl_path = Path::new("image.jxl");
let png_path = Path::new("image.png");
convert_jxl_to_png(jxl_path, png_path).await?;
// Process JXL file with custom handling
process_jxl_file(jxl_path, Some(|temp_png_path| async move {
// Remove letterboxing from the temporary PNG
imx::remove_letterbox(&temp_png_path).await?;
// The modified temp PNG will be used
Ok(())
})).await?;
Ok(())
}
use std::path::PathBuf;
use anyhow::Result;
use imx::xyplot::{PlotConfig, create_plot, LabelAlignment};
fn create_image_grid() -> Result<()> {
// Create a 2x3 grid of images
let images = vec![
PathBuf::from("img1.png"),
PathBuf::from("img2.png"),
PathBuf::from("img3.png"),
PathBuf::from("img4.png"),
PathBuf::from("img5.png"),
PathBuf::from("img6.png"),
];
let config = PlotConfig {
images,
output: PathBuf::from("grid_output.png"),
rows: 2,
row_labels: vec!["Set A".to_string(), "Set B".to_string()],
column_labels: vec!["Low".to_string(), "Medium".to_string(), "High".to_string()],
column_label_alignment: LabelAlignment::Center,
row_label_alignment: LabelAlignment::Start,
debug_mode: false,
top_padding: 60, // Extra space for column labels
left_padding: 80, // Extra space for row labels
font_size: None, // Use default font size
};
create_plot(&config)?;
Ok(())
}
use imx::numeric::{f32_to_i32, f32_to_u8, i32_to_u32};
fn numeric_example() {
// Convert float to integer with rounding
let float_val = 123.7;
let int_val = f32_to_i32(float_val);
assert_eq!(int_val, 124); // Rounds to nearest
// Handle NaN values safely
let nan_val = f32_to_i32(f32::NAN);
assert_eq!(nan_val, 0); // NaN becomes 0
// Convert to byte values (for image processing)
let color_val = 240.8;
let byte_val = f32_to_u8(color_val);
assert_eq!(byte_val, 241); // Rounds to nearest, clamps to 0-255
// Safe signed to unsigned conversion
let signed_val = -5;
let unsigned_val = i32_to_u32(signed_val);
assert_eq!(unsigned_val, 0); // Negative becomes 0
}
Always use platform-agnostic path handling:
use std::path::Path;
// Good
let img_path = Path::new("images").join("photo.jpg");
// Avoid platform-specific separators
// let img_path = "images/photo.jpg"; // Works on Unix but not Windows
Ensure your runtime is configured for async functions:
use tokio::runtime::Runtime;
// Setup a basic tokio runtime
let rt = Runtime::new().unwrap();
rt.block_on(async {
// Call async imx functions here
imx::remove_letterbox(Path::new("image.jpg")).await.unwrap();
});
The library uses a sophisticated layout algorithm for grid plots:
For debugging layouts, set debug_mode: true in your PlotConfig to see a color-coded visualization of the calculated layout.