Local Development Setup
Relevant source files
The following files were used as context for generating this wiki page:This document outlines the necessary steps and components for setting up and running the hdrify application in a local development environment. The project consists of a Rust backend using the warp web framework and a vanilla HTML, CSS, and JavaScript frontend. The core functionality relies on an external command-line tool, ImageMagick, for image processing.
The local setup involves installing prerequisites, running the backend server, and accessing the web interface through a browser. The server handles file uploads, processes images via ImageMagick, and serves the static frontend files.
Sources: README.md, src/main.rs, Cargo.toml
Prerequisites
To run the application locally, the following dependencies must be installed on your system.
| Dependency | Purpose | Installation Command (Example) |
|---|---|---|
| Rust | To compile and run the backend server. | (Via rustup) |
| ImageMagick | For the core image processing pipeline. | brew install imagemagick or apt-get install imagemagick |
Sources: README.md:32-33
Backend Dependencies
The Rust backend relies on several crates defined in Cargo.toml. These are automatically downloaded and managed by Cargo when building the project.
| Crate | Version | Purpose |
|---|---|---|
warp | 0.3 | The web server framework used for routing. |
tokio | 1.0 | The asynchronous runtime for the server. |
serde | 1.0 | For serializing and deserializing data structures. |
base64 | 0.21 | For decoding and encoding image data. |
tempfile | 3.0 | To create temporary files for image processing. |
Sources: Cargo.toml:6-14
System Architecture
The application follows a simple client-server architecture. The frontend is a single-page application that communicates with a backend API endpoint. The backend orchestrates the image processing by invoking the ImageMagick CLI tool.
This diagram illustrates the high-level interaction between the components.
Sources: src/main.rs:200-209, static/script.js:251-260
Running the Application
To start the local development server, execute the following command from the root of the repository:
cargo run
This command compiles the Rust source code and starts the warp server. The server will listen for requests on http://localhost:3000.
// src/main.rs:211-212
println!("Server starting on http://localhost:3000");
warp::serve(routes).run(([0, 0, 0, 0], 3000)).await;
Sources: README.md:34, src/main.rs:211-212
Backend
The backend is a single Rust application responsible for serving the frontend and handling the image processing API.
Sources: src/main.rs
Routing
The server defines three main routes:
- Root (
/): Serves the mainindex.htmlfile. - Static Files (
/static/*): Serves all files from thestaticdirectory (CSS, JS, images). - Upload (
/upload): APOSTendpoint that accepts form data for image processing.
// src/main.rs:198-209
#[tokio::main]
async fn main() {
// Serve static files
let static_files = warp::fs::dir("static");
// Route for form upload (only endpoint)
let upload = warp::path("upload")
.and(warp::post())
.and(warp::body::form())
.and_then(handle_upload);
// Root route serves index.html
let index = warp::path::end().and(warp::fs::file("static/index.html"));
let routes = index.or(static_files).or(upload);
// ...
}
Sources: src/main.rs:198-209
API Endpoint: POST /upload
This is the sole API endpoint for the application. It receives an image and an HDR value, processes the image, and returns the result.
Request Body (application/x-www-form-urlencoded)
| Parameter | Type | Description |
|---|---|---|
image | String | Base64-encoded string of the image data. |
hdr_value | Float | The HDR intensity value (e.g., 1.5). Defaults to 1.5. |
Sources: src/main.rs:19-24, static/script.js:253-254
Response Body (application/json)
The server responds with a JSON object defined by the ProcessResponse struct.
| Field | Type | Description |
|---|---|---|
success | boolean | true if processing was successful, false otherwise. |
message | String | A status message (e.g., "Image processed successfully"). |
image_data | String (Option) | Base64-encoded string of the processed HDR image. |
Sources: src/main.rs:9-14
Image Processing Flow
The handle_upload function contains the core logic for processing an image. The following diagram details the sequence of operations.
Sources: src/main.rs:18-140
The ImageMagick command pipeline is central to the application's functionality.
// src/main.rs:91-109
let output = Command::new("magick")
.arg(input_file.path())
.arg("-define")
.arg("quantum:format=floating-point")
.arg("-colorspace")
.arg("RGB")
.arg("-auto-gamma")
.arg("-evaluate")
.arg("Multiply")
.arg(hdr_value.to_string())
.arg("-evaluate")
.arg("Pow")
.arg("0.9")
.arg("-colorspace")
.arg("sRGB")
.arg("-depth")
.arg("16")
.arg("-profile")
.arg("2020_profile.icc")
.arg(output_file.path())
.output();
Sources: src/main.rs:91-109, README.md:23-29
Frontend
The frontend is built with vanilla HTML, CSS, and JavaScript, located in the static directory. It provides the user interface for uploading images and adjusting the HDR effect.
Sources: static/index.html, static/script.js, static/style.css
UI Components
The UI is defined in static/index.html and consists of:
- An upload area (
#uploadArea) for drag-and-drop or click-to-upload. - An image display area (
#imageDisplay) to show the processed result. - A control section (
#controls) with a slider (#hdrSlider) to adjust the HDR value. - Download and Reset buttons.
Sources: static/index.html:24-50
Client-Side Logic
The static/script.js file contains an HDRify class that manages the application's state and user interactions.
This sequence diagram shows the client-side flow when a user uploads a file and adjusts the slider.
Sources: static/script.js:1-355
Key features of the client-side logic include:
- File Validation: Checks for supported formats (JPEG, PNG, WebP) and size (max 10MB) before uploading.
- State Management: The
HDRifyclass tracks the current image data, original image URL, and file name. - API Communication: Uses
fetchto send aPOSTrequest to the/uploadendpoint. - Debouncing: A 250ms debounce on the slider input prevents excessive API calls while the user is adjusting the value.
- Caching: Caches processed images on the client to provide instant feedback when returning to a previously used HDR value.
Sources: static/script.js:141-155, static/script.js:106-112, static/script.js:218-223