This commit is contained in:
Matthew Deville 2026-01-21 22:14:29 +01:00
commit ab7734c229
6 changed files with 4208 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

4063
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]
edition = "2024"
name = "remove_background"
version = "0.1.0"
[dependencies]
clap = { version = "4.5", features = ["derive"] }
image = "0.25"
reqwest = { version = "0.13", features = ["blocking"] }
show-image = { version = "0.14", features = ["image"] }

71
flake.nix Normal file
View file

@ -0,0 +1,71 @@
{
description = "Remove background Rust project with X11/Wayland support";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
rust-overlay.url = "github:oxalica/rust-overlay";
flake-utils.url = "github:numtide/flake-utils";
};
outputs =
{
self,
nixpkgs,
rust-overlay,
flake-utils,
}:
flake-utils.lib.eachDefaultSystem (
system:
let
overlays = [ (import rust-overlay) ];
pkgs = import nixpkgs { inherit system overlays; };
stdenv = pkgs.stdenvAdapters.useMoldLinker pkgs.clangStdenv;
rustToolchain = pkgs.rust-bin.stable.latest.default;
nativeBuildInputs = with pkgs; [
rustToolchain
mold
pkg-config
clang
];
xorgBuildInputs = with pkgs; [
xorg.libX11
xorg.libXcursor
xorg.libXi
xorg.libXrandr
];
waylandBuildInputs = with pkgs; [
libxkbcommon
wayland
];
buildInputs = xorgBuildInputs ++ waylandBuildInputs;
mkShell = pkgs.mkShell.override {
stdenv = stdenv;
};
in
{
packages.default = pkgs.rustPlatform.buildRustPackage {
inherit stdenv buildInputs nativeBuildInputs;
pname = (builtins.fromTOML (builtins.readFile ./Cargo.toml)).package.name;
version = (builtins.fromTOML (builtins.readFile ./Cargo.toml)).package.version;
src = ./.;
cargoLock = {
lockFile = ./Cargo.lock;
};
};
devShells.default = mkShell {
inherit buildInputs nativeBuildInputs;
RUST_BACKTRACE = 1;
shellHook = ''
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${pkgs.lib.makeLibraryPath buildInputs}"
'';
};
}
);
}

2
rust-toolchain.toml Normal file
View file

@ -0,0 +1,2 @@
[toolchain]
channel = "stable"

61
src/main.rs Normal file
View file

@ -0,0 +1,61 @@
use clap::Parser;
use image::GenericImageView;
use show_image::{AsImageView, create_window, event};
use std::error::Error;
#[derive(Parser)]
#[command(name = "remove_background")]
#[command(about = "Download and display an image (future: background removal)", long_about = None)]
struct Args {
#[arg(help = "URL of the image to download and display")]
url: String,
}
#[show_image::main]
fn main() -> Result<(), Box<dyn Error>> {
// Parse command line arguments
let args = Args::parse();
println!("Downloading image from: {}", args.url);
// Download the image with a user agent (using blocking client)
let client = reqwest::blocking::Client::builder()
.user_agent("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36")
.build()?;
let response = client.get(&args.url).send()?;
if !response.status().is_success() {
return Err(format!("Failed to download image: HTTP {}", response.status()).into());
}
let bytes = response.bytes()?;
println!("Downloaded {} bytes", bytes.len());
// Load the image
let img = image::load_from_memory(&bytes)?;
let (width, height) = img.dimensions();
println!("Loaded image: {}x{}", width, height);
// Create a window and display the image.
let window = create_window("image", Default::default())?;
window.set_image(
"downloaded image",
&img.as_image_view().map_err(|e| e.to_string())?,
)?;
println!("Image displayed. Press ESC to close the window.");
// Event loop - wait for ESC key to close
for event in window.event_channel()? {
if let event::WindowEvent::KeyboardInput(event) = event {
if event.input.key_code == Some(event::VirtualKeyCode::Escape)
&& event.input.state.is_pressed()
{
println!("ESC pressed, closing...");
break;
}
}
}
Ok(())
}