Skip to content

Commit

Permalink
Merge pull request #15 from transcental/create-quilts
Browse files Browse the repository at this point in the history
Add functionality to create quilts and fix the file sorting
  • Loading branch information
transcental authored Dec 6, 2024
2 parents 017a106 + 01a3cf0 commit 3a65cbe
Show file tree
Hide file tree
Showing 8 changed files with 996 additions and 130 deletions.
494 changes: 494 additions & 0 deletions src-tauri/Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ serde = { version = "1", features = ["derive"] }
serde_json = "1"
tauri-plugin-dialog = "2"
tauri-plugin-process = "2"
image = "0.25.5"

[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
tauri-plugin-updater = "2"
Expand Down
124 changes: 98 additions & 26 deletions src-tauri/src/commands.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use image::{GenericImageView, ImageBuffer};
use serde::Serialize;
use std::fs;
use std::{fs, path::Path};

#[derive(Serialize)]
pub struct FilesMap {
Expand Down Expand Up @@ -63,35 +64,106 @@ pub fn delete_move_files_in_folder(folder: String, files: Vec<String>, delete: b

#[tauri::command]
pub fn sort_files(frame_folders: Vec<String>, final_folder: String, views: usize) {
println!("Folders: {:?}", frame_folders);
let no_of_folders: usize = frame_folders.len();
for i in 0..no_of_folders {
for folder in &frame_folders {
let files = fs::read_dir(folder.clone()).unwrap();
for file in files {
let filename = file.unwrap().file_name();
let current_view = filename
.to_str()
.unwrap()
.split("_v")
.collect::<Vec<&str>>()[1];
let current_view = current_view.split(".").collect::<Vec<&str>>()[0];
let current_view = match current_view.parse::<usize>() {
Ok(view) => view,
Err(_) => {
println!("Failed to parse view: {}", current_view);
continue;
for (i, folder) in frame_folders.iter().enumerate() {
println!("Sorting folder: {}", folder);
let files = fs::read_dir(folder).unwrap();
for file in files {
let filename = file.unwrap().file_name();
let current_view = filename
.to_str()
.unwrap()
.split("_v")
.collect::<Vec<&str>>()[1];
let current_view = current_view.split(".").collect::<Vec<&str>>()[0];
let current_view = match current_view.parse::<usize>() {
Ok(view) => view,
Err(_) => {
println!("Failed to parse view: {}", current_view);
continue;
}
};
if current_view < (views / no_of_folders) * (i + 1)
&& current_view >= (views / no_of_folders) * i
{
let original_file = Path::new(&folder).join(&filename);
let original_file = original_file.to_str().unwrap();
let path = Path::new(&final_folder).join(&filename);
let path = path.to_str().unwrap();
fs::copy(original_file, path).unwrap();
}
}
}
}

#[tauri::command]
pub fn make_quilt(sorted_folder: String, output_folder: String, columns: usize, rows: usize) {
let quilt_size = columns * rows;

let mut quilt_layout: Vec<Vec<String>> = vec![vec!['-'.to_string(); columns]; rows];
let mut current_row = 0;
let mut current_column = 0;

let mut dir: Vec<_> = fs::read_dir(sorted_folder)
.unwrap()
.map(|entry| entry.unwrap().path())
.collect();
dir.sort_by(|a, b| a.file_name().unwrap().cmp(b.file_name().unwrap()));
let no_of_quilts = dir.len() / quilt_size;

for quilt_i in 0..no_of_quilts {
for i in 0..quilt_size {
let filename = dir[i + quilt_size * quilt_i].to_str().unwrap().to_string();
if filename.contains("_v") {
quilt_layout[current_row][current_column] = filename;
current_column += 1;
if current_column == columns {
current_column = 0;
current_row += 1;
}
} else {
println!("INVALID FILE FOUND '_v': {}", filename);
}
}
current_row = 0;

let first_img_path = &quilt_layout[0][0];
let first_img = image::open(first_img_path).unwrap();
let (img_width, img_height) = first_img.dimensions();

let quilt_width = img_width * columns as u32;
let quilt_height = img_height * rows as u32;

let mut quilt = ImageBuffer::new(quilt_width, quilt_height);
let mut current_width: u32;
let mut current_height: u32 = 0;
for row in 0..rows {
current_width = 0;
for column in 0..columns {
let current_img_path = &quilt_layout[row][column];
let current_img = image::open(current_img_path).unwrap();
let current_img_map = current_img.to_rgba8();

for x in 0..img_width {
for y in 0..img_height {
let pixel = current_img_map.get_pixel(x, y);
quilt.put_pixel(
current_width + x,
quilt_height - 1 - (current_height + y),
*pixel,
);
}
};
if current_view < (views / no_of_folders) * (i + 1)
&& current_view >= (views / no_of_folders) * i
{
let original_file = std::path::Path::new(&folder).join(&filename);
let original_file = original_file.to_str().unwrap();
let path = std::path::Path::new(&final_folder).join(&filename);
let path = path.to_str().unwrap();
fs::copy(original_file, path).unwrap();
}
current_width += img_width;
}
current_height += img_height;
}

let output_path =
std::path::Path::new(&output_folder).join(format!("quilt_{}.png", quilt_i));
// flip the quilt vertically
let quilt = image::imageops::flip_vertical(&quilt);
quilt.save(&output_path).unwrap();
}
}
3 changes: 2 additions & 1 deletion src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ pub fn run() {
commands::delete_file,
commands::move_file,
commands::delete_move_files_in_folder,
commands::sort_files
commands::sort_files,
commands::make_quilt
])
.run(tauri::generate_context!())
.expect("error while running tauri application");
Expand Down
40 changes: 40 additions & 0 deletions src/components/button.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<script lang="ts">
export let disabled: boolean = false;
export let onClick: () => void;
export let type: "button" | "submit" | "reset" = "button";
export let ariaLabel: string;
export let close: boolean = false;
</script>

<button {type} {disabled} aria-label={ariaLabel} onclick={onClick} class:close>
<slot></slot>
</button>

<style>
button {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
padding: 5px;
margin: 5px;
border: 1px solid #646cff;
border-radius: 5px;
background-color: #646cff;
color: white;
}
button {
cursor: pointer;
}
button[disabled] {
background-color: #646cff40;
color: #646cff80;
cursor: not-allowed;
}
button.close {
background-color: #ff3e00;
border-color: #ff3e00;
}
</style>
37 changes: 37 additions & 0 deletions src/components/folderInput.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<script lang="ts">
import { open } from "@tauri-apps/plugin-dialog";
const openFolder = async () => {
const result = await open({
directory: true,
multiple: multiple,
});
if (result) {
callback(result);
}
};
export let multiple: boolean = false;
export let callback: (path: string) => void;
</script>

<button on:click={openFolder}>
<slot></slot>
</button>

<style>
button {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
padding: 5px;
margin: 5px;
border: 1px solid #646cff;
border-radius: 5px;
background-color: #646cff;
color: white;
}
button {
cursor: pointer;
}
</style>
Loading

0 comments on commit 3a65cbe

Please sign in to comment.