Architecture Overview
Relevant source files
The following files were used as context for generating this wiki page:The hdrify application is a minimalist web service designed to convert standard dynamic range (SDR) images into high dynamic range (HDR) equivalents. The architecture is a classic client-server model, comprising a vanilla JavaScript frontend for user interaction and a Rust-based backend that orchestrates the image processing. The core image manipulation is not performed by the Rust application itself but is delegated to the ImageMagick command-line tool, which the backend invokes as an external process.
This separation of concerns allows the frontend to focus on providing a responsive and intuitive user experience, while the backend handles the business logic of data validation and process execution. The system is designed to be simple, with a single API endpoint for image processing and static file serving for the user interface.
Sources: README.md:3-5, src/main.rs:168-183
System Components
The application consists of three primary components: a web frontend, a web backend, and an external command-line tool for image processing.
This diagram illustrates the high-level interaction between the frontend, the Rust backend server, and the ImageMagick CLI.
Sources: src/main.rs:81, static/script.js:270-277
Frontend Architecture
The frontend is built with vanilla HTML, CSS, and JavaScript, providing a modern, single-page application experience without a framework. It is responsible for all user interactions, including file uploads, real-time control adjustments, and displaying the processed image.
Sources: README.md:43, static/index.html, static/script.js
UI Components
The user interface is defined in static/index.html and styled by static/style.css. Key interactive elements are managed by the HDRify JavaScript class.
| Element ID | Description | Source File |
|---|---|---|
uploadArea | Drag-and-drop area and click-to-upload button. | static/index.html:27 |
imageInput | The hidden file input element. | static/index.html:30 |
imageDisplay | Container for the processed image preview. | static/index.html:33 |
resultImage | The <img> tag that displays the original and processed images. | static/index.html:34 |
processingOverlay | A spinner overlay shown during backend processing. | static/index.html:35 |
controls | A container for the HDR slider and action buttons. | static/index.html:42 |
hdrSlider | A range input (0.5 to 3.0) to control the HDR intensity. | static/index.html:45 |
downloadButton | An anchor tag that allows downloading the processed image. | static/index.html:47 |
resetButton | A button to reset the UI to its initial state. | static/index.html:50 |
error | A container to display error messages. | static/index.html:69 |
Client-Side Logic (HDRify Class)
All client-side logic is encapsulated within the HDRify class in static/script.js. This class manages the application's state, handles DOM events, and communicates with the backend API.
This diagram shows the main properties and methods of the HDRify class, which controls the frontend's state and behavior.
Sources: static/script.js:1-365
User Interaction Flow
The following sequence diagram details the flow from a user uploading a file to seeing the processed result.
This sequence shows the client-side validation, API communication, and UI updates for both the initial upload and subsequent adjustments.
Sources: static/script.js:141-188, static/script.js:233-300
Backend Architecture
The backend is a lightweight web server written in Rust using the warp framework. Its responsibilities are to serve the static frontend files and provide a single API endpoint for image processing.
Sources: src/main.rs, Cargo.toml
Dependencies
The backend relies on several key Rust crates to function.
| Crate | Version | Purpose |
|---|---|---|
warp | 0.3 | Web server framework for routing and handlers. |
tokio | 1.0 | Asynchronous runtime. |
serde | 1.0 | Serialization/deserialization of data. |
base64 | 0.21 | Decoding and encoding Base64 image data. |
tempfile | 3.0 | Creating temporary files for ImageMagick. |
Sources: Cargo.toml:7-15
Server and Routing
The server is started in the main function. It sets up three main routes:
- Root (
/): Serves the mainindex.htmlfile. - Static Files (
/static/*): Serves the directory containingscript.js,style.css, and images. - Upload (
/upload): APOSTendpoint that handles the image processing request.
All routes are configured with a permissive CORS policy (allow_any_origin). The server listens on 0.0.0.0:3000.
Sources: src/main.rs:168-183
API Endpoint: POST /upload
This is the sole API endpoint for the application. It accepts a form-urlencoded body.
Request Body Parameters:
| Parameter | Type | Description |
|---|---|---|
image | String | A Base64-encoded string of the source image. |
hdr_value | Float | The HDR intensity multiplier (defaults to 1.5). |
Response Body (ProcessResponse struct):
The server responds with a JSON object based on 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" or an error detail. |
image_data | String/null | A Base64-encoded string of the processed PNG image if successful. |
Sources: src/main.rs:8-12, src/main.rs:15-20, static/script.js:271-273
Image Processing Flow
The handle_upload async function contains the core backend logic. It performs several steps to securely process the user's image.
This flowchart details the validation and processing pipeline within the handle_upload function on the backend.
Sources: src/main.rs:13-121
ImageMagick Pipeline
The core of the HDR effect is achieved by executing an ImageMagick magick command with a specific set of arguments. This pipeline is derived from an external guide and hardcoded into the backend.
The command executed is:
magick <input_file> \
-define quantum:format=floating-point \
-colorspace RGB \
-auto-gamma \
-evaluate Multiply <hdr_value> \
-evaluate Pow 0.9 \
-colorspace sRGB \
-depth 16 \
-profile 2020_profile.icc \
<output_file>
Pipeline Stages:
-define quantum:format=floating-point: Switches to a high-precision floating-point format to prevent clipping during brightness adjustments.-colorspace RGB: Converts the image to a linear RGB colorspace.-auto-gamma: Applies automatic gamma correction.-evaluate Multiply <hdr_value>: Multiplies the brightness of each pixel by the user-provided HDR value. This is the key step for the HDR effect.-evaluate Pow 0.9: Applies a power curve adjustment.-colorspace sRGB: Converts the image back to the standard sRGB colorspace.-depth 16: Sets the color depth to 16 bits.-profile 2020_profile.icc: Applies the Rec. 2020 color profile, which is necessary for displays to interpret the image as HDR.
Sources: src/main.rs:81-98, README.md:28-35
Conclusion
The architecture of hdrify is a pragmatic and effective combination of modern web technologies. It leverages a lightweight Rust backend for performance and safety, a vanilla JavaScript frontend for a responsive UI, and the powerful, industry-standard ImageMagick tool for the specialized task of image processing. This design results in a simple, maintainable, and focused application that successfully delivers its core feature: creating HDR-infused images from user uploads.
Sources: README.md:3, src/main.rs, static/script.js