Cleaned up matrix transformation and added functionality to save to pdf

This commit is contained in:
2024-02-23 17:16:21 -06:00
parent 60abb4cd3d
commit 37be4f19d7
4 changed files with 252 additions and 49 deletions

203
Cargo.lock generated
View File

@@ -55,6 +55,12 @@ dependencies = [
"rustc-demangle",
]
[[package]]
name = "bit_field"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
[[package]]
name = "bitflags"
version = "1.3.2"
@@ -67,6 +73,18 @@ version = "3.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d32a994c2b3ca201d9b263612a374263f05e7adde37c4707f693dcd375076d1f"
[[package]]
name = "bytemuck"
version = "1.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2ef034f05691a48569bd920a96c81b9d91bbad1ab5ac7c4616c1f6ef36cb79f"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cairo-rs"
version = "0.17.10"
@@ -117,6 +135,21 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "color_quant"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "crc32fast"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa"
dependencies = [
"cfg-if",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.5"
@@ -142,6 +175,12 @@ version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
[[package]]
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "either"
version = "1.10.0"
@@ -154,6 +193,31 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "exr"
version = "1.72.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4"
dependencies = [
"bit_field",
"flume 0.11.0",
"half",
"lebe",
"miniz_oxide",
"rayon-core",
"smallvec",
"zune-inflate",
]
[[package]]
name = "fdeflate"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645"
dependencies = [
"simd-adler32",
]
[[package]]
name = "field-offset"
version = "0.3.6"
@@ -174,6 +238,16 @@ dependencies = [
"rustc_version",
]
[[package]]
name = "flate2"
version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
name = "flume"
version = "0.10.14"
@@ -187,6 +261,15 @@ dependencies = [
"spin",
]
[[package]]
name = "flume"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181"
dependencies = [
"spin",
]
[[package]]
name = "fragile"
version = "2.0.0"
@@ -355,6 +438,16 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "gif"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2"
dependencies = [
"color_quant",
"weezl",
]
[[package]]
name = "gimli"
version = "0.28.1"
@@ -564,6 +657,16 @@ dependencies = [
"system-deps",
]
[[package]]
name = "half"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc52e53916c08643f1b56ec082790d1e86a32e58dc5268f897f313fbae7b4872"
dependencies = [
"cfg-if",
"crunchy",
]
[[package]]
name = "hashbrown"
version = "0.14.3"
@@ -582,6 +685,24 @@ version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd"
[[package]]
name = "image"
version = "0.24.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d"
dependencies = [
"bytemuck",
"byteorder",
"color_quant",
"exr",
"gif",
"jpeg-decoder",
"num-traits",
"png",
"qoi",
"tiff",
]
[[package]]
name = "indexmap"
version = "2.2.3"
@@ -592,6 +713,15 @@ dependencies = [
"hashbrown",
]
[[package]]
name = "jpeg-decoder"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0"
dependencies = [
"rayon",
]
[[package]]
name = "js-sys"
version = "0.3.68"
@@ -601,6 +731,12 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "lebe"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
[[package]]
name = "libc"
version = "0.2.153"
@@ -651,6 +787,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
dependencies = [
"adler",
"simd-adler32",
]
[[package]]
@@ -662,6 +799,15 @@ dependencies = [
"getrandom",
]
[[package]]
name = "num-traits"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.16.0"
@@ -764,6 +910,19 @@ version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]]
name = "png"
version = "0.17.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1"
dependencies = [
"bitflags",
"crc32fast",
"fdeflate",
"flate2",
"miniz_oxide",
]
[[package]]
name = "proc-macro-crate"
version = "1.3.1"
@@ -807,6 +966,15 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "qoi"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001"
dependencies = [
"bytemuck",
]
[[package]]
name = "quote"
version = "1.0.35"
@@ -843,7 +1011,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c16f3fad883034773b7f5af4d7e865532b8f3641e5a8bab2a34561a8d960d81"
dependencies = [
"async-trait",
"flume",
"flume 0.10.14",
"fragile",
"futures",
"gtk4",
@@ -959,6 +1127,12 @@ dependencies = [
"serde",
]
[[package]]
name = "simd-adler32"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
[[package]]
name = "slab"
version = "0.4.9"
@@ -1044,6 +1218,17 @@ dependencies = [
"syn 2.0.49",
]
[[package]]
name = "tiff"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e"
dependencies = [
"flate2",
"jpeg-decoder",
"weezl",
]
[[package]]
name = "tokio"
version = "1.36.0"
@@ -1213,12 +1398,19 @@ checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838"
name = "waywrite"
version = "0.1.0"
dependencies = [
"image",
"ocrs",
"relm4",
"rten",
"rten-tensor",
]
[[package]]
name = "weezl"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082"
[[package]]
name = "winapi"
version = "0.3.9"
@@ -1258,3 +1450,12 @@ checksum = "d90f4e0f530c4c69f62b80d839e9ef3855edc9cba471a160c4d692deed62b401"
dependencies = [
"memchr",
]
[[package]]
name = "zune-inflate"
version = "0.2.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02"
dependencies = [
"simd-adler32",
]

View File

@@ -10,3 +10,4 @@ relm4 = "0.6.*"
rten-tensor = "0.3.*"
rten = "0.3.1"
ocrs = "0.4.*"
image = "0.24.9"

View File

@@ -3,7 +3,7 @@ use gtk::prelude::{BoxExt, ButtonExt, GtkWindowExt, OrientableExt, WidgetExt, Ge
use gtk::cairo::{Context, Operator};
use relm4::drawing::DrawHandler;
use waywrite::process_point::print_written;
use waywrite::process_point::print_words;
use waywrite::Point;
#[derive(Debug)]
@@ -113,7 +113,7 @@ impl SimpleComponent for AppModel {
match message {
AppInput::Input => {
print_written(&self.points).unwrap();
print_words(&self.points).unwrap();
}
AppInput::AddPoint((x, y)) => {
self.points.push(Point { x, y, new_line: false })

View File

@@ -5,12 +5,20 @@ use std::time::Instant;
use rten_tensor::{NdTensor, AsView};
use rten::Model;
use ocrs::{OcrEngine, OcrEngineParams};
use image::{ColorType, ImageFormat};
use crate::Point;
const MATRIX_SIZE: usize = 800;
const MATRIX_LEN: usize = 800;
const TEXT_MATRIX_RATIO: f64 = 0.5;
const LINE_WIDTH: f64 = 10.0;
pub fn print_written(points: &Vec<Point>) -> Result<(), Box<dyn Error>> {
const MATRIX_X_SIZE: f64 = MATRIX_LEN as f64;
const TEXT_X_SIZE: f64 = (MATRIX_X_SIZE as f64) * TEXT_MATRIX_RATIO;
const TEXT_X_OFFSET: f64 = (MATRIX_X_SIZE - TEXT_X_SIZE) / 2.0;
const LINE_WIDTH_X_OFFSET: f64 = LINE_WIDTH / 2.0;
pub fn print_words(points: &Vec<Point>) -> Result<(), Box<dyn Error>> {
let begin = Instant::now();
let processed_data = process(points);
@@ -28,7 +36,10 @@ fn process(points: &Vec<Point>) -> NdTensor<f32, 3> {
let matrix = to_matrix(points);
let y_len = matrix[0].len();
let x_len = matrix[0][0].len();
let image_data: Box<[u8]> = matrix.iter().flatten().flatten().map(|f| if *f > 0.5 { u8::from(0) } else { u8::from(255) }).collect();
let data: Vec<f32> = matrix.into_iter().flatten().flatten().map(|f| f as f32).collect();
image::save_buffer_with_format("./image.png", &image_data, x_len as u32, y_len as u32, ColorType::L8, ImageFormat::Png).unwrap();
NdTensor::from_data([1, y_len, x_len], data)
@@ -91,53 +102,43 @@ fn to_matrix(points: &Vec<Point>) -> Vec<Vec<Vec<f64>>> {
let y_len = max_y - min_y;
let y_ratio = y_len / x_len;
let matrix_y_size = MATRIX_X_SIZE * y_ratio;
let text_y_size = TEXT_X_SIZE * y_ratio;
let text_y_offset = TEXT_X_OFFSET * y_ratio;
let line_width_y_offset = LINE_WIDTH_X_OFFSET * y_ratio;
let x_size = MATRIX_SIZE as f64 * 0.5;
let y_size = (MATRIX_SIZE as f64 * 0.5) * y_ratio;
let x_offset = (MATRIX_SIZE as f64 - x_size) / 2.0;
let y_offset = ((MATRIX_SIZE as f64 * y_ratio) - y_size) / 2.0;
let x_scale = x_size / x_len;
let y_scale = y_size / y_len;
let mut matrix: Vec<Vec<f64>> = vec![vec![0.0; MATRIX_SIZE]; (MATRIX_SIZE as f64 * y_ratio) as usize];
let x_scale = MATRIX_X_SIZE / x_len;
let y_scale = matrix_y_size / y_len;
let scaled_points = points
let mut matrix: Vec<Vec<f64>> = vec![
vec![0.0; MATRIX_LEN]; (matrix_y_size as usize) + 1
];
let scaled_points: Vec<((f64, f64), bool)> = points
.iter()
.map(|point| {
let x_scaled = ((point.x - min_x) * x_scale) + x_offset;
let y_scaled = ((point.y - min_y) * y_scale) + y_offset;
let x_scaled = ((point.x - min_x) * x_scale) + TEXT_X_OFFSET;
let y_scaled = ((point.y - min_y) * y_scale) + text_y_offset;
((x_scaled, y_scaled), point.new_line)
}).collect::<Vec<_>>();
let line_width_x = MATRIX_SIZE as f64 / 80.0;
let line_width_y = (MATRIX_SIZE as f64 * y_ratio) / 80.0;
}).collect();
let mut last_x = 0.0;
let mut last_y = 0.0;
for ((x, y), newline) in scaled_points {
for ((current_x, current_y), newline) in scaled_points {
if !newline {
let curr_x_start = x - (line_width_x / 2.0);
let curr_x_end = x + (line_width_x / 2.0);
let curr_x_start = current_x - LINE_WIDTH_X_OFFSET;
let curr_x_end = current_x + LINE_WIDTH_X_OFFSET;
let last_x_start = last_x - (line_width_x / 2.0);
let last_x_end = last_x + (line_width_x / 2.0);
let last_x_start = last_x - LINE_WIDTH_X_OFFSET;
let last_x_end = last_x + LINE_WIDTH_X_OFFSET;
let top_y: f64;
let bottom_y: f64;
if y > last_y {
top_y = y + ((line_width_y / 2.0) * y_scale);
bottom_y = last_y - ((line_width_y / 2.0) * y_scale);
} else {
top_y = last_y + ((line_width_y / 2.0) * y_scale);
bottom_y = y - ((line_width_y / 2.0) * y_scale);
}
let top_y = current_y.max(last_y) + line_width_y_offset;
let bottom_y = current_y.min(last_y) - line_width_y_offset;
let start_x = (last_x_start.min(curr_x_start)) as usize;
let end_x = (last_x_end.max(curr_x_end)) as usize + 1;
@@ -145,25 +146,25 @@ fn to_matrix(points: &Vec<Point>) -> Vec<Vec<Vec<f64>>> {
for x in start_x..(end_x + 1) {
let left_line_y = line(x as f64, (last_x_start, last_y), (curr_x_start, y));
let right_line_y = line(x as f64, (last_x_end, last_y), (curr_x_end, y));
let left_line_y = line(x as f64, (last_x_start, last_y), (curr_x_start, current_y));
let right_line_y = line(x as f64, (last_x_end, last_y), (curr_x_end, current_x));
let top_line = left_line_y.max(right_line_y);
let bottom_line = left_line_y.min(right_line_y);
let top_line_y = left_line_y
.max(right_line_y)
.min(top_y) as usize;
let bottom_line_y = left_line_y
.min(right_line_y)
.max(bottom_y) as usize;
let top_line = top_line.min(top_y) as usize + 1;
let bottom_line = bottom_line.max(bottom_y) as usize;
for line_y in bottom_line..(top_line + 1) {
matrix[line_y][x] = 1.0;
for y in bottom_line_y..(top_line_y + 1) {
matrix[y][x] = 1.0;
}
}
}
last_x = x;
last_y = y;
last_x = current_x;
last_y = current_y;
}
vec![matrix]