Function bodies 18 total
bench_convert function · rust · L3-L20 (18 LOC)benches/convert_bench.rs
pub fn bench_convert(c: &mut Criterion) {
let img = "image2ascii/convert/testdata/husky_300x300.jpg";
let mut group = c.benchmark_group("convert");
for &w in &[80u32, 120u32, 160u32] {
group.throughput(Throughput::Elements((w as u64) * 100));
group.bench_with_input(BenchmarkId::from_parameter(w), &w, |b, &width| {
b.iter(|| {
let cfg = Config {
width: Some(width),
..Default::default()
};
let _ = convert_path_to_ascii(img, &cfg).unwrap();
});
});
}
group.finish();
}main function · rust · L6-L29 (24 LOC)examples/basic.rs
fn main() -> anyhow::Result<()> {
// Optional arg: path to image. If not provided, search ./examples for the first image.
let args: Vec<String> = env::args().skip(1).collect();
let img_path = if let Some(p) = args.first() {
PathBuf::from(p)
} else if let Some(p) = find_example_image()? {
println!("[info] Using example image: {}", p.display());
p
} else {
println!(
"No image argument provided and no image found under ./examples.\n - Run: cargo run --example basic -- <image_path>\n - Or place a .jpg/.jpeg/.png/.gif in ./examples and rerun"
);
std::process::exit(1);
};
let cfg = Config {
width: Some(80),
..Default::default()
};
let ascii = convert_path_to_ascii(&img_path, &cfg)?;
println!("{}", ascii);
Ok(())
}find_example_image function · rust · L30-L47 (18 LOC)examples/basic.rs
fn find_example_image() -> anyhow::Result<Option<PathBuf>> {
let dir = PathBuf::from("examples");
if !dir.exists() {
return Ok(None);
}
let exts = ["jpg", "jpeg", "png", "gif"];
for entry in fs::read_dir(dir)? {
let entry = entry?;
let p = entry.path();
if let Some(ext) = p.extension().and_then(|e| e.to_str()) {
if exts.iter().any(|x| x.eq_ignore_ascii_case(ext)) {
return Ok(Some(p));
}
}
}
Ok(None)
}default function · rust · L28-L43 (16 LOC)src/lib.rs
fn default() -> Self {
Self {
width: None,
height: None,
scale: None,
charset: DEFAULT_CHARSET.to_string(),
invert: false,
color: false,
brightness: 0.0,
gamma: 1.0,
contrast: 1.0,
threshold: None,
aspect: 2.0,
filter: FilterType::Triangle,
}
}convert_path_to_ascii function · rust · L45-L49 (5 LOC)src/lib.rs
pub fn convert_path_to_ascii<P: AsRef<Path>>(path: P, cfg: &Config) -> Result<String> {
let img = image::open(path)?;
Ok(convert_image_to_ascii(&img, cfg))
}convert_bytes_to_ascii function · rust · L50-L54 (5 LOC)src/lib.rs
pub fn convert_bytes_to_ascii(bytes: &[u8], cfg: &Config) -> Result<String> {
let img = image::load_from_memory(bytes)?;
Ok(convert_image_to_ascii(&img, cfg))
}convert_gif_bytes_to_ascii_frames function · rust · L55-L68 (14 LOC)src/lib.rs
pub fn convert_gif_bytes_to_ascii_frames(bytes: &[u8], cfg: &Config) -> Result<Vec<String>> {
let cursor = Cursor::new(bytes);
let decoder = GifDecoder::new(cursor)?;
let frames = decoder.into_frames();
let mut out = Vec::new();
for f in frames {
let f = f?;
let buf = f.into_buffer();
let dynimg = DynamicImage::ImageRgba8(buf);
out.push(convert_image_to_ascii(&dynimg, cfg));
}
Ok(out)
}Repobility · code-quality intelligence platform · https://repobility.com
convert_gif_path_to_ascii_frames function · rust · L69-L76 (8 LOC)src/lib.rs
pub fn convert_gif_path_to_ascii_frames<P: AsRef<Path>>(
path: P,
cfg: &Config,
) -> Result<Vec<String>> {
let bytes = std::fs::read(path)?;
convert_gif_bytes_to_ascii_frames(&bytes, cfg)
}convert_image_to_ascii function · rust · L77-L81 (5 LOC)src/lib.rs
pub fn convert_image_to_ascii(img: &DynamicImage, cfg: &Config) -> String {
let lines = convert_image_to_ascii_lines(img, cfg);
lines.join("\n")
}convert_image_to_ascii_lines function · rust · L82-L136 (55 LOC)src/lib.rs
pub fn convert_image_to_ascii_lines(img: &DynamicImage, cfg: &Config) -> Vec<String> {
let (tw, th) = target_size(img.dimensions(), cfg);
let resized = img.resize_exact(tw, th, cfg.filter).to_rgba8();
(0..th)
.into_par_iter()
.map(|y| {
let mut line = String::with_capacity(tw as usize);
for x in 0..tw {
let px = resized.get_pixel(x, y);
let (r, g, b, a) = (px[0], px[1], px[2], px[3]);
// blend alpha on black background
let (r, g, b) = if a < 255 {
let af = (a as f32) / 255.0;
(
(r as f32 * af) as u8,
(g as f32 * af) as u8,
(b as f32 * af) as u8,
)
} else {
(r, g, b)
};
let mut lum = luminance(r, g, b);
// brightness offset
if cfg.brightness !luminance function · rust · L184-L188 (5 LOC)src/lib.rs
fn luminance(r: u8, g: u8, b: u8) -> f32 {
// linearized approximation is omitted; keep simple sRGB weights
(0.2126 * (r as f32) + 0.7152 * (g as f32) + 0.0722 * (b as f32)) / 255.0
}map_luma_to_char function · rust · L189-L199 (11 LOC)src/lib.rs
fn map_luma_to_char(lum: f32, charset: &str, invert: bool) -> char {
let mut chars: Vec<char> = charset.chars().collect();
if chars.is_empty() {
chars = DEFAULT_CHARSET.chars().collect();
}
let n = chars.len();
let v = if invert { 1.0 - lum } else { lum }.clamp(0.0, 1.0);
let idx = (v * (n as f32 - 1.0)).round() as usize;
chars[idx]
}test_luminance_basic function · rust · L207-L212 (6 LOC)src/lib.rs
fn test_luminance_basic() {
assert!((luminance(0, 0, 0) - 0.0).abs() < 1e-6);
assert!((luminance(255, 255, 255) - 1.0).abs() < 1e-6);
let gray = luminance(128, 128, 128);
assert!(gray > 0.4 && gray < 0.6);
}test_map_luma_to_char_invert function · rust · L215-L223 (9 LOC)src/lib.rs
fn test_map_luma_to_char_invert() {
let cs = " .#"; // 0 -> space, 1 -> '#'
let c1 = map_luma_to_char(0.0, cs, false);
let c2 = map_luma_to_char(1.0, cs, false);
let c3 = map_luma_to_char(0.0, cs, true);
assert_eq!(c1, ' ');
assert_eq!(c2, '#');
assert_eq!(c3, '#');
}test_target_size_defaults function · rust · L226-L231 (6 LOC)src/lib.rs
fn test_target_size_defaults() {
let cfg = Config::default();
let (w, h) = super::target_size((400, 200), &cfg);
assert_eq!(w, 80);
assert!(h > 0);
}Methodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
main function · rust · L78-L159 (82 LOC)src/main.rs
fn main() -> anyhow::Result<()> {
let args = Cli::parse();
let use_color = args.color && !args.no_color && ansi_supported();
let cfg = Config {
width: args.width,
height: args.height,
scale: args.scale,
charset: args.charset,
invert: args.invert,
color: use_color,
brightness: args.brightness,
gamma: args.gamma,
contrast: args.contrast,
threshold: args.threshold,
aspect: args.aspect,
..Default::default()
};
if args.animate {
// Render frames (GIF) and animate to stdout with clear between frames
let frames: Vec<String> = if args.input.as_os_str() == "-" {
use std::io::Read;
let mut buf = Vec::new();
io::stdin().read_to_end(&mut buf)?;
match convert_gif_bytes_to_ascii_frames(&buf, &cfg) {
Ok(f) => f,
Err(_) => vec![convert_bytes_to_ascii(&buf, &cfg)?],
}
} elansi_supported function · rust · L160-L185 (26 LOC)src/main.rs
fn ansi_supported() -> bool {
// Disable if NO_COLOR is set
if std::env::var_os("NO_COLOR").is_some() {
return false;
}
// Only enable on TTY
if !atty::is(atty::Stream::Stdout) {
return false;
}
// On Windows, try enabling VT processing
#[cfg(windows)]
if enable_windows_ansi() {
return true;
}
// Heuristic using TERM
if let Ok(term) = std::env::var("TERM") {
let t = term.to_ascii_lowercase();
return t.contains("xterm")
|| t.contains("ansi")
|| t.contains("vt100")
|| t.contains("screen");
}
// On modern Windows terminals truecolor is typically supported; default to true
cfg!(windows)
}enable_windows_ansi function · rust · L188-L205 (18 LOC)src/main.rs
fn enable_windows_ansi() -> bool {
use windows_sys::Win32::System::Console::{
GetConsoleMode, GetStdHandle, SetConsoleMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING,
STD_OUTPUT_HANDLE,
};
unsafe {
let handle = GetStdHandle(STD_OUTPUT_HANDLE);
if handle == 0 {
return false;
}
let mut mode: u32 = 0;
if GetConsoleMode(handle, &mut mode) == 0 {
return false;
}
let new_mode = mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING;
SetConsoleMode(handle, new_mode) != 0
}
}