initial commit
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
1370
Cargo.lock
generated
Normal file
1370
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
8
Cargo.toml
Normal file
8
Cargo.toml
Normal 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
33
README.md
Normal 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:
|
||||
|
||||

|
||||
|
||||
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.
|
69
src/main.rs
Normal file
69
src/main.rs
Normal 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.");
|
||||
}
|
Reference in New Issue
Block a user