initial commit

This commit is contained in:
2025-05-25 14:03:11 +02:00
commit 2455abe13d
6 changed files with 1481 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

1370
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

8
Cargo.toml Normal file
View File

@ -0,0 +1,8 @@
[package]
name = "unicodeartgenerator"
version = "0.1.0"
edition = "2021"
[dependencies]
image = "0.25"
rfd = "0.13"

33
README.md Normal file
View File

@ -0,0 +1,33 @@
# Unicode art generator
Simple ascii art generator written in Rust to generate unicode art using only these characters: `▀`, `▄`, `█`.
## How does it work
It take an image and checks where there is black color and where isnt. Then the black pixels are converted to the "white" part of the character. So the black parts of the image is going to be visible.
### Sample image:
![Sample image](./house.png)
Converts to:
```
▄▄▄▄▄ ▄▀▄
█ █▄▀ ▀▄
█ ▄▀ ▄▀▀▀▄ ▀▄
█▄▀ ▄▀ ▀▄ ▀▄
▄▀ ▄▀ ▀▄ ▀▄
▄▀ ▄▀ ▀▄ ▀▄
▀▄▄█ ▄▄▄▄▄▄ █▄▄▀
█ █ █ █▀▀▀▀▀█ █
█ █ █ █ █ █
█ █ ▄█ █ █ █
█ █ █ █▄▄▄▄▄█ █
█ █ █ █
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
```
---
**NOTE**: There is no resize option and will not be, for proper outputs you should resize the image first in some other editor (like GIMP) and then put it to this program.

BIN
house.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 B

69
src/main.rs Normal file
View File

@ -0,0 +1,69 @@
use rfd::FileDialog;
use std::fs::File;
use std::io::{BufWriter, Write};
fn main() {
let file = FileDialog::new()
.add_filter("Image files", &["png", "jpg", "jpeg", "bmp"])
.pick_file();
let Some(path) = file else {
eprintln!("No image file selected.");
return;
};
let img = image::open(&path).expect("Failed to load image.");
let rgb_img = img.to_rgb8();
let (width, height) = rgb_img.dimensions();
let threshold: u8 = 40;
let mut ascii_lines: Vec<String> = Vec::with_capacity(height as usize);
for y in (0..height).step_by(2) {
let mut line = String::with_capacity((width as usize) * 2);
for x in 0..width {
let top_pixel = rgb_img.get_pixel(x, y);
let [tr, tg, tb] = top_pixel.0;
let top_black = tr < threshold && tg < threshold && tb < threshold;
let symbol = if y + 1 < height {
let bottom_pixel = rgb_img.get_pixel(x, y + 1);
let [br, bg, bb] = bottom_pixel.0;
let bottom_black = br < threshold && bg < threshold && bb < threshold;
match (top_black, bottom_black) {
(true, true) => "",
(true, false) => "",
(false, true) => "",
(false, false) => " ",
}
} else {
// Only top row is available
if top_black { "" } else { " " }
};
line.push_str(symbol);
}
ascii_lines.push(line);
}
let save_path = FileDialog::new()
.add_filter("Text files", &["txt"])
.set_file_name("ascii_output.txt")
.save_file();
let Some(output_path) = save_path else {
eprintln!("No save location selected.");
return;
};
let file = File::create(output_path).expect("Failed to create file");
let mut writer = BufWriter::new(file);
for line in ascii_lines {
writeln!(writer, "{}", line).expect("Failed to write to file");
}
println!("ASCII art saved successfully.");
}