Initial commit

This commit is contained in:
yanorei32 2024-07-23 12:12:06 +09:00
commit 049177604f
4 changed files with 1314 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

1196
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

10
Cargo.toml Normal file
View File

@ -0,0 +1,10 @@
[package]
name = "yabinary"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = { version = "4.5.9", features = ["derive"] }
image = "0.25.2"

107
src/main.rs Normal file
View File

@ -0,0 +1,107 @@
use clap::{Parser, ValueEnum};
use image::ImageReader;
use std::fs::File;
use std::io::{Read, Write};
use std::path::PathBuf;
const WHITE: u8 = 0x88;
const BLACK: u8 = 0xCC;
const SCREEN_WIDTH: usize = 16;
#[derive(ValueEnum, Clone, Copy)]
enum Color {
White,
Black,
}
impl Color {
fn as_bytes(&self) -> u8 {
match self {
Color::White => WHITE,
Color::Black => BLACK,
}
}
}
impl std::fmt::Display for Color {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::White => f.write_str("white"),
Self::Black => f.write_str("black"),
}
}
}
#[derive(Parser)]
struct Cli {
#[arg(long, requires_all=["header_lines"])]
header_from: Option<PathBuf>,
#[arg(long)]
header_lines: Option<usize>,
image: PathBuf,
#[arg(long, requires_all=["footer_lines"])]
footer_from: Option<PathBuf>,
#[arg(long)]
footer_lines: Option<usize>,
#[arg(long, default_value_t = Color::White)]
background: Color,
output: PathBuf,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let c = Cli::parse();
let img = ImageReader::open(c.image)?.decode()?;
if SCREEN_WIDTH < img.width() as usize {
println!(
"WARN: {} pixels are ignored",
img.width() as usize - SCREEN_WIDTH
);
}
let mut output = File::create(&c.output)?;
if let Some(header_path) = c.header_from {
let mut buffer = vec![0; c.header_lines.unwrap() * SCREEN_WIDTH];
File::open(header_path)?.read_exact(&mut buffer)?;
output.write(&buffer)?;
};
for row in img.to_rgba8().rows() {
let buffer: Vec<_> = (0..SCREEN_WIDTH)
.into_iter()
.zip(
row.into_iter()
.map(|v| {
let brightness =
(v[0] as f32 / 256.0 + v[1] as f32 / 256.0 + v[2] as f32 / 256.0) / 3.0;
if brightness > 0.2 {
Color::White
} else {
Color::Black
}
})
.chain(std::iter::repeat(c.background)),
)
.map(|(_, color)| color.as_bytes())
.collect();
output.write(&buffer)?;
}
if let Some(footer_path) = c.footer_from {
let mut buffer = vec![0; c.footer_lines.unwrap() * SCREEN_WIDTH];
File::open(footer_path)?.read_exact(&mut buffer)?;
output.write(&buffer)?;
};
Ok(())
}