Last active
August 4, 2022 00:10
-
-
Save gitcrtn/a9bb22408cb4906c0f2b5f0427a8e1db to your computer and use it in GitHub Desktop.
Bitmap font generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "font-img-gen" | |
version = "0.1.0" | |
edition = "2021" | |
[dependencies] | |
image = "0.24.2" | |
imageproc = "0.23.0" | |
rustop = "1.1.2" | |
rusttype = "0.9.2" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::fs::File; | |
use std::io::{BufReader, Read}; | |
use image::{Rgb, RgbImage}; | |
use imageproc::drawing::{draw_filled_rect_mut, draw_text_mut, text_size}; | |
use imageproc::rect::Rect; | |
use rustop::opts; | |
use rusttype::{Font, Scale}; | |
fn hex_to_color(color: &String) -> Rgb<u8> { | |
let red = u8::from_str_radix(&color[0..2], 16).unwrap(); | |
let green = u8::from_str_radix(&color[2..4], 16).unwrap(); | |
let blue = u8::from_str_radix(&color[4..], 16).unwrap(); | |
Rgb([red, green, blue]) | |
} | |
fn hex_to_characters(start_hex: &String, end_hex: &String, hexes: &String) -> Vec<char> { | |
if hexes.len() == 0 { | |
let start = u32::from_str_radix(start_hex, 16).unwrap(); | |
let end = u32::from_str_radix(end_hex, 16).unwrap() + 1; | |
if start > end { | |
panic!("start hex must be smaller than end hex."); | |
} | |
(start..end) | |
.map(|num| char::from_u32(num).unwrap()) | |
.collect() | |
} else { | |
hexes | |
.split(',') | |
.map(|hex| u32::from_str_radix(hex, 16).unwrap()) | |
.map(|num| char::from_u32(num).unwrap()) | |
.collect() | |
} | |
} | |
fn main() { | |
let (args, _rest) = opts! { | |
opt output:String="out.png".to_string(), desc:"output file name"; | |
opt font:String="font.ttf".to_string(), desc:"font file path"; | |
opt height:u32=16, desc:"font height"; | |
opt scale:f32=1.0, desc:"font scale"; | |
opt bgcolor:String="FFFFFF".to_string(), desc:"background color RRGGBB"; | |
opt fgcolor:String="000000".to_string(), desc:"foreground color RRGGBB"; | |
opt starthex:String="20".to_string(), desc:"start character hex"; | |
opt endhex:String="7E".to_string(), desc:"end character hex"; | |
opt hexes:String="".to_string(), desc:"character hex list with comma as delimiter"; | |
}.parse_or_exit(); | |
let characters = hex_to_characters(&args.starthex, &args.endhex, &args.hexes); | |
let current_dir = std::env::current_dir().unwrap(); | |
let output_path = current_dir.join(args.output); | |
let font_path = current_dir.join(args.font); | |
let bg_color = hex_to_color(&args.bgcolor); | |
let fg_color = hex_to_color(&args.fgcolor); | |
let scale = Scale { | |
x: args.height as f32 * args.scale, | |
y: args.height as f32 * args.scale, | |
}; | |
let width = args.height * (characters.len() as u32); | |
let height = args.height; | |
let font_file = File::open(font_path).unwrap(); | |
let mut reader = BufReader::new(font_file); | |
let mut buffer = Vec::new(); | |
reader.read_to_end(&mut buffer).unwrap(); | |
let font = Font::try_from_bytes(&buffer).unwrap(); | |
let mut image = RgbImage::new(width, height); | |
draw_filled_rect_mut(&mut image, Rect::at(0, 0).of_size(width, height), bg_color); | |
let height = height as i32; | |
for (i, char) in characters.iter().enumerate() { | |
let text1 = char.to_string(); | |
let (w, _h) = text_size(scale, &font, &text1); | |
let offset = (height - w) / 2; | |
let offset = if offset < 0 { 0 } else { offset }; | |
let offset = height * (i as i32) + offset; | |
draw_text_mut(&mut image, fg_color, offset, 0, scale, &font, &text1); | |
} | |
let _ = image.save(output_path).unwrap(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment