feat: converted to Godot app

This commit is contained in:
Bram Dingelstad 2024-11-17 00:00:24 +01:00
parent 50a53af97d
commit 80b36d14bd
10 changed files with 739 additions and 50 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
/target
*.jpg
!background.jpg
.godot

218
Cargo.lock generated
View file

@ -20,6 +20,15 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "approx"
version = "0.5.1"
@ -166,6 +175,24 @@ dependencies = [
"toml",
]
[[package]]
name = "gdextension-api"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3f2fc05d781fbc1da92d13480d464b2bf66b2e8cf230746f3a9ded3eb9bf6de"
[[package]]
name = "gensym"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "913dce4c5f06c2ea40fc178c06f777ac89fc6b1383e90c254fafb1abe4ba3c82"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.87",
"uuid",
]
[[package]]
name = "getrandom"
version = "0.1.16"
@ -174,7 +201,18 @@ checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
dependencies = [
"cfg-if 1.0.0",
"libc",
"wasi",
"wasi 0.9.0+wasi-snapshot-preview1",
]
[[package]]
name = "getrandom"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if 1.0.0",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
]
[[package]]
@ -187,6 +225,95 @@ dependencies = [
"weezl",
]
[[package]]
name = "glam"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e05e7e6723e3455f4818c7b26e855439f7546cf617ef669d1adedb8669e5cb9"
[[package]]
name = "godot"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "246203d267e0523aa8877e7d5145fa34a5bbdb1a5c8e135f4dacbdeb074c1fc9"
dependencies = [
"godot-core",
"godot-macros",
]
[[package]]
name = "godot-bindings"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b664d294f99139f828b76b6e9955aa1b7455cc03fac08917b57a4578d22489e7"
dependencies = [
"gdextension-api",
]
[[package]]
name = "godot-cell"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28ee918b831ef1c455283b96d8527d0ddee556363c757fc18e01c75935bf7fb8"
[[package]]
name = "godot-codegen"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51e6d5d3f836cdc4487de17f3422f7b25c3f95a11472132f8e8ef698dd907cd4"
dependencies = [
"godot-bindings",
"heck",
"nanoserde",
"proc-macro2",
"quote",
"regex",
]
[[package]]
name = "godot-core"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96dbdc7c65fb4a2dc58b66c2bb91f2b092f55afa42d2ffd509fa454f123f3e51"
dependencies = [
"glam",
"godot-bindings",
"godot-cell",
"godot-codegen",
"godot-ffi",
]
[[package]]
name = "godot-ffi"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da4a1f0d0c8c1443ba8732f011a532ae35793e276567e2fcd90a8ef9c09d90c9"
dependencies = [
"gensym",
"godot-bindings",
"godot-codegen",
"libc",
"paste",
]
[[package]]
name = "godot-macros"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff936aabcda6b8bcba69a4367938369e41bcdf17601f07ddda153947a481a0f0"
dependencies = [
"godot-bindings",
"proc-macro2",
"quote",
"venial",
]
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "image"
version = "0.23.14"
@ -239,7 +366,9 @@ dependencies = [
name = "instinct"
version = "0.1.0"
dependencies = [
"godot",
"image 0.25.5",
"lazy_static",
"photon-rs",
]
@ -325,6 +454,21 @@ dependencies = [
"autocfg",
]
[[package]]
name = "nanoserde"
version = "0.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5de9cf844ab1e25a0353525bd74cb889843a6215fa4a0d156fd446f4857a1b99"
dependencies = [
"nanoserde-derive",
]
[[package]]
name = "nanoserde-derive"
version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e943b2c21337b7e3ec6678500687cdc741b7639ad457f234693352075c082204"
[[package]]
name = "node-sys"
version = "0.4.2"
@ -457,6 +601,12 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "paste"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "perlin2d"
version = "0.2.6"
@ -579,7 +729,7 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom",
"getrandom 0.1.16",
"libc",
"rand_chacha",
"rand_core 0.5.1",
@ -611,7 +761,7 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom",
"getrandom 0.1.16",
]
[[package]]
@ -644,6 +794,35 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebac11a9d2e11f2af219b8b8d833b76b1ea0e054aa0e8d8e9e4cbde353bdf019"
[[package]]
name = "regex"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "rulinalg"
version = "0.4.2"
@ -702,18 +881,18 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "serde"
version = "1.0.214"
version = "1.0.215"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5"
checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.214"
version = "1.0.215"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
dependencies = [
"proc-macro2",
"quote",
@ -923,6 +1102,25 @@ version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
[[package]]
name = "uuid"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a"
dependencies = [
"getrandom 0.2.15",
]
[[package]]
name = "venial"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6816bc32f30bf8dd1b3adb04de8406c7bf187d2f923bd9e4c0b99365d012613f"
dependencies = [
"proc-macro2",
"quote",
]
[[package]]
name = "version_check"
version = "0.9.5"
@ -935,6 +1133,12 @@ version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.78"

View file

@ -3,10 +3,18 @@ name = "instinct"
version = "0.1.0"
edition = "2021"
[[bin]]
name = "cli"
src = "src/main.rs"
[lib]
# name = "instinct"
crate-type = ["cdylib"]
# [[bin]]
# name = "cli"
[dependencies]
godot = { version = "0.1.3", features = ["experimental-threads"] }
image = { version = "0.25.5", features = ["jpeg"], default-features = false }
lazy_static = "1.5.0"
photon-rs = "0.3.2"

View file

@ -0,0 +1,8 @@
[configuration]
entry_symbol = "gdext_rust_init"
compatibility_minimum = 4.3
reloadable = true
[libraries]
macos.debug.arm64 = "res://target/debug/libinstinct.dylib"
macos.release.arm64 = "res://target/release/libinstinct.dylib"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

110
godot/App.gd Normal file
View file

@ -0,0 +1,110 @@
extends Control
@onready
var template = $Printer/PictureLayer/Template
signal done_loading_picture(picture)
signal done_processing_photo(photo)
var files_being_processed = 0
func _ready():
get_viewport().files_dropped.connect(
func(files):
var thread = Thread.new()
thread.start(on_files_dropped.bind(files), Thread.PRIORITY_LOW)
$PhotoProcess.process_files(files)
)
$PhotoProcess.done_with_photo.connect(
func(photo):
var thread = Thread.new()
thread.start(print_out.bind(photo), Thread.PRIORITY_LOW)
)
done_loading_picture.connect(animate_picture)
done_processing_photo.connect(animate_printing_out)
template.get_parent().remove_child(template)
func on_files_dropped(files):
var index = 0
for path in files:
var image = Image.load_from_file(path)
var texture = ImageTexture.create_from_image(image)
var picture = template.duplicate()
picture.get_node('Texture').texture = texture
picture.global_position = Vector2(randf_range(-300, 300), -300) * 2.0
picture.rotation = randf() * TAU * randf_range(1, 3)
call_deferred('emit_signal', 'done_loading_picture', picture, index)
index += 1
func animate_picture(picture, index):
$Printer/PictureLayer.add_child(picture)
await get_tree().create_timer(index).timeout
var tween = create_tween().set_parallel()
var time = 1.0 + randf()
tween.tween_property(
picture,
'rotation',
.0,
time
)
tween.tween_property(
picture,
'global_position',
$Printer/Back/AnimationTarget.global_position,
time
)
tween.chain().tween_property(
picture,
'global_position',
$Printer/Back/AnimationTarget.global_position + Vector2.DOWN * 100,
1.0
)
tween.play()
await tween.finished
files_being_processed += 1
func print_out(photo):
var image = Image.load_from_file(photo)
var texture = ImageTexture.create_from_image(image)
var picture = template.duplicate()
picture.get_node('Texture').texture = texture
call_deferred('emit_signal', 'done_processing_photo', picture)
func animate_printing_out(picture):
$Printer/PictureOutLayer.add_child(picture)
files_being_processed -= 1
picture.global_position = $Printer/Back/AnimationTarget.global_position + Vector2.DOWN * 100
picture.rotation = .0
var tween = create_tween()
var time = 3.0 + randf()
tween.tween_property(
picture,
'global_position',
$Printer/Back/AnimationTarget.global_position + Vector2.DOWN * 200,
time
)
tween.play()
func _process(_delta):
if files_being_processed > 0:
$Printer/Front.rotation = sin(Time.get_ticks_msec()) * .025
else:
$Printer/Front.rotation = .0

278
godot/App.tscn Normal file
View file

@ -0,0 +1,278 @@
[gd_scene load_steps=7 format=3 uid="uid://dxtriafl731dx"]
[ext_resource type="Script" path="res://godot/App.gd" id="1_mppeb"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_5uavs"]
bg_color = Color(0.2, 0.058, 0.058, 1)
corner_radius_top_left = 32
corner_radius_top_right = 32
corner_radius_bottom_right = 16
corner_radius_bottom_left = 16
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_5u4ls"]
bg_color = Color(0.2, 0.058, 0.058, 1)
corner_radius_bottom_right = 16
corner_radius_bottom_left = 16
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_c0w2o"]
bg_color = Color(0.6, 0.174, 0.174, 1)
corner_radius_top_left = 32
corner_radius_top_right = 32
corner_radius_bottom_right = 16
corner_radius_bottom_left = 16
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_kj77j"]
bg_color = Color(0.87665, 0.8633, 0.89, 1)
corner_radius_top_left = 100
corner_radius_top_right = 100
corner_radius_bottom_right = 100
corner_radius_bottom_left = 100
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_7puhn"]
bg_color = Color(0.43, 0.1247, 0.1247, 1)
corner_radius_top_left = 32
corner_radius_top_right = 32
[node name="App" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
script = ExtResource("1_mppeb")
[node name="PhotoProcess" type="PhotoProcess" parent="."]
[node name="Poloroid" type="Control" parent="."]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="Background" type="ColorRect" parent="Poloroid"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
color = Color(0.99, 0.9504, 0.9504, 1)
[node name="Black" type="ColorRect" parent="Poloroid"]
layout_mode = 1
anchors_preset = -1
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 52.0
offset_top = 52.0
offset_right = -52.0
offset_bottom = -96.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
color = Color(0.08, 0.0768, 0.0768, 1)
metadata/_edit_use_anchors_ = true
[node name="StatusText" type="RichTextLabel" parent="Poloroid"]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -200.0
offset_top = -69.0
offset_right = 200.0
offset_bottom = 66.0
grow_horizontal = 2
grow_vertical = 2
theme_override_font_sizes/normal_font_size = 32
bbcode_enabled = true
text = "[center]Drop in your photos to get started 🫴 🌁
[/center]"
fit_content = true
[node name="Printer" type="Control" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
[node name="Background" type="ColorRect" parent="Printer"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
color = Color(0.82, 0.7872, 0.7872, 1)
[node name="StatusText" type="RichTextLabel" parent="Printer"]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -200.0
offset_top = 121.0
offset_right = 200.0
offset_bottom = 256.0
grow_horizontal = 2
grow_vertical = 2
theme_override_colors/default_color = Color(0, 0, 0, 1)
theme_override_font_sizes/normal_font_size = 32
bbcode_enabled = true
text = "[center]Drop in your photos to get started 🫴 🌁
[/center]"
fit_content = true
[node name="Back" type="Panel" parent="Printer"]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -100.0
offset_top = -178.0
offset_right = 100.0
offset_bottom = -29.0
grow_horizontal = 2
grow_vertical = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_5uavs")
[node name="AnimationTarget" type="Control" parent="Printer/Back"]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -0.5
offset_top = -0.5
offset_right = 0.5
offset_bottom = 0.5
grow_horizontal = 2
grow_vertical = 2
[node name="PictureLayer" type="Control" parent="Printer"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
[node name="Template" type="Control" parent="Printer/PictureLayer"]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -165.0
offset_top = -437.0
offset_right = -164.0
offset_bottom = -436.0
grow_horizontal = 2
grow_vertical = 2
pivot_offset = Vector2(85, 95)
[node name="Texture" type="TextureRect" parent="Printer/PictureLayer/Template"]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -85.5
offset_top = -73.0
offset_right = 85.5
offset_bottom = 73.0
grow_horizontal = 2
grow_vertical = 2
pivot_offset = Vector2(85, 95)
expand_mode = 1
stretch_mode = 5
[node name="Exit" type="Panel" parent="Printer"]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -100.0
offset_top = 50.0
offset_right = 100.0
offset_bottom = 96.0
grow_horizontal = 2
grow_vertical = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_5u4ls")
[node name="PictureOutLayer" type="Control" parent="Printer"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
[node name="Front" type="Panel" parent="Printer"]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -170.0
offset_top = -98.0
offset_right = 170.0
offset_bottom = 51.0
grow_horizontal = 2
grow_vertical = 2
pivot_offset = Vector2(171, 75)
theme_override_styles/panel = SubResource("StyleBoxFlat_c0w2o")
[node name="Button" type="Panel" parent="Printer/Front"]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = 129.0
offset_top = -55.5
offset_right = 149.0
offset_bottom = -35.5
grow_horizontal = 2
grow_vertical = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_kj77j")
[node name="Mouth" type="Panel" parent="Printer/Front"]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -100.0
offset_top = 51.5
offset_right = 100.0
offset_bottom = 74.5
grow_horizontal = 2
grow_vertical = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_7puhn")

24
project.godot Normal file
View file

@ -0,0 +1,24 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=5
[application]
run/main_scene="res://godot/App.tscn"
config/features=PackedStringArray("4.3")
boot_splash/bg_color=Color(0.988235, 0.94902, 0.94902, 1)
boot_splash/show_image=false
[display]
window/size/viewport_width=500
window/size/viewport_height=500
window/size/resizable=false
window/size/always_on_top=true
window/size/extend_to_title=true

View file

@ -1,33 +0,0 @@
use instinct::{process_image, save_image};
use std::thread;
fn main() {
let mut files = std::env::args().collect::<Vec<String>>();
files.remove(0);
println!("\n📸 Starting instinct processing ✨");
let mut threads = vec![];
for file in files {
threads.push(thread::spawn(move || {
let path = std::path::Path::new(&file);
println!("🎞️ Processing {:?}", path.file_name().unwrap());
let image = process_image(path);
let mut new_file_path = std::path::PathBuf::from(path);
new_file_path.set_file_name(format!(
"{} - instagram compatible.jpg",
path.file_name()
.unwrap()
.to_str()
.unwrap()
.replace(".jpg", "")
));
save_image(image, new_file_path.to_str().unwrap());
println!("🖼️ done w/ file, wrote to: {new_file_path:#?}");
}));
}
for handle in threads {
handle.join().unwrap();
}
}

View file

@ -14,12 +14,19 @@ use photon_rs::{
// TODO: Add option for 4:5 export and 1:1 export
pub fn process_image(path: &std::path::Path) -> PhotonImage {
let mut image = open_image(path.to_str().unwrap()).unwrap();
let mut image = open_image(path.to_str().expect("to parse path to string"))
.expect("to open image with Photon");
println!("opened image");
let padding = 36;
let intended_size_in_frame = 1080 - padding;
let mut background = open_image("background.jpg").unwrap();
let mut background = PhotonImage::new_from_byteslice({
let mut image =
Image::create(1080, 1080, false, Format::RGB8).expect("to be able to create an image");
image.fill(Color::WHITE);
image.save_jpg_to_buffer().to_vec()
});
let width = image.get_width();
let height = image.get_height();
@ -69,8 +76,6 @@ pub fn process_image(path: &std::path::Path) -> PhotonImage {
);
}
// save_image(background, "result.jpg").unwrap();
// println!("done!");
background
}
@ -80,14 +85,98 @@ pub fn save_image(image: PhotonImage, path: &str) {
let width = image.get_width();
let height = image.get_height();
let buffer = ImageBuffer::from_vec(width, height, raw_pixels).unwrap();
println!("attempting to make image buffer");
let buffer = ImageBuffer::from_vec(width, height, raw_pixels)
.expect("to be able to build an image buffer");
let image = ImageRgba8(buffer).into_rgb8();
let file = std::fs::File::create(path).unwrap();
println!("attempting to save to {path:#?}");
let file = std::fs::File::create(path).expect("to able to create a file");
let ref mut buff = BufWriter::new(file);
let mut encoder = JpegEncoder::new_with_quality(buff, 100);
encoder
.encode(&image.as_bytes(), width, height, Rgb8)
.unwrap();
.expect("to encode the JPEG to a file");
println!("saved to {path:#?}");
}
use godot::{
engine::{image::Format, Image},
prelude::*,
};
struct PhotoProcessingExtension;
#[gdextension]
unsafe impl ExtensionLibrary for PhotoProcessingExtension {}
#[derive(GodotClass)]
#[class(base=Node)]
struct PhotoProcess {
base: Base<Node>,
}
#[godot_api]
impl INode for PhotoProcess {
fn init(base: Base<Node>) -> Self {
Self { base }
}
}
#[godot_api]
impl PhotoProcess {
#[signal]
fn done_with_photo(path: GString);
#[func]
fn process_files(&mut self, files: PackedStringArray) {
godot_print!("attempting to process files: {files:#?}! ✨");
let mut threads = vec![];
let instance_id = self.base().instance_id();
for file in files.to_vec() {
godot_print!("attempting to process file: {file:#?}! 🤔");
let file = file.to_string().clone();
threads.push(std::thread::spawn(move || {
let path = std::path::Path::new(&file);
println!(
"🎞️ Processing {:?}",
path.file_name().expect("to turn path into a filename")
);
let image = process_image(path);
println!("Done processing!");
let mut new_file_path = std::path::PathBuf::from(path);
new_file_path.set_file_name(format!(
"{} - instagram compatible.jpg",
path.file_name()
.expect("to get path filename")
.to_str()
.expect("to convert filename to string")
.replace(".jpg", "")
));
save_image(
image,
new_file_path
.to_str()
.expect("to turn new_path into a string"),
);
Gd::<Node>::from_instance_id(instance_id).call_deferred(
"emit_signal".into(),
&[
Variant::from("done_with_photo"),
Variant::from(new_file_path.to_str().unwrap()),
],
);
println!("🖼️ done w/ file, wrote to: {new_file_path:#?}");
}));
}
// for handle in threads {
// handle.join().expect("to join threads");
// }
}
}