Home
Relevant source files
The following files were used as context for generating this wiki page:hdrify is a minimalist web application designed to convert standard dynamic range (SDR) images into high dynamic range (HDR) equivalents. It provides a simple user interface for uploading an image, adjusting the HDR intensity in real-time, and downloading the processed result. The application is built with a Rust backend using the warp web server framework and a vanilla HTML/CSS/JavaScript frontend.
The core functionality relies on an external command-line tool, ImageMagick, to perform the image processing. The entire system is designed to be lightweight and easy to run, with options for both local execution and Docker deployment. The primary use case is creating HDR-infused images, such as for Slack emoji, that appear brighter on supported displays.
Sources: README.md:3-5, src/main.rs:175-178, static/index.html:10-14
Architecture Overview
The application follows a simple client-server architecture. The frontend, consisting of static HTML, CSS, and JavaScript files, is served by the Rust backend. The client-side JavaScript handles all user interactions, file uploads, and communication with the single API endpoint. The backend is responsible for receiving the image data, validating it, invoking the ImageMagick process, and returning the processed image.
This diagram illustrates the high-level architecture of the hdrify application.
Frontend
The frontend is responsible for the user interface and client-side logic. It is built with vanilla HTML, CSS, and JavaScript, emphasizing a modern design and responsive user experience.
Sources: README.md:44, static/index.html, static/script.js, static/style.css
UI Components
The user interface is defined in static/index.html and styled by static/style.css. It features a "glass-morphism" design. The main components are:
| Component ID | Element | Description | Source File |
|---|---|---|---|
uploadArea | <div> | A drag-and-drop area for file uploads. Also clickable to open a file dialog. | static/index.html:26-30 |
imageDisplay | <div> | Container that appears after an image is uploaded, showing the processed result. | static/index.html:32-39 |
hdrSlider | <input type="range"> | A slider to control the HDR intensity from 0.5 to 3.0. | static/index.html:44 |
downloadButton | <a> | A button to download the processed HDR image. | static/index.html:47-49 |
resetButton | <button> | A button to reset the interface to its initial state. | static/index.html:50-52 |
error | <div> | A container to display error messages to the user. | static/index.html:69-71 |
Sources: static/index.html, README.md:7
Client-Side Logic
All client-side logic is encapsulated within the HDRify class in static/script.js.
Key Properties
currentImageData: Stores the Base64-encoded string of the original uploaded image.originalImageUrl: A data URL for the original image, used for previews.imageCache: AMapobject used to cache processed images. The key is the HDR value (e.g., "1.5"), and the value is the Base64 image data. This prevents re-processing when the user adjusts the slider back to a previously used value.
Sources: static/script.js:3-7
Core Methods
handleFile(file): Validates the uploaded file's type (JPEG, PNG, WebP) and size (max 10MB). If valid, it uses aFileReaderto read the file as a data URL, stores the Base64 data, and triggers the initial image processing.processImage(hdrValue): This is the main function for processing. It first checks theimageCachefor a result. If a cached version exists, it's displayed immediately. Otherwise, it constructs aPOSTrequest to the/uploadendpoint with the image data and HDR value. Upon a successful response, it updates the image display, enables the download button, and caches the result.reset(): Clears all session data (currentImageData,imageCache, etc.), resets UI elements to their initial state, and transitions the view back to the upload area.transitionToImageView(): Manages the smooth visual transition from the upload area to the image display view, using opacity and blur filters for effect.
Sources: static/script.js:133-164, static/script.js:183-241, static/script.js:268-297, static/script.js:166-181
User Interaction Flow
The following sequence diagram shows the complete flow from a user uploading a file to receiving the processed image.
Sources: static/script.js:133-241, src/main.rs:16-125
Backend
The backend is a single-file Rust application using the warp framework. Its primary role is to expose one API endpoint, process the image using ImageMagick, and handle static file serving.
Sources: src/main.rs, Cargo.toml
Dependencies
The project relies on several key Rust crates defined in Cargo.toml.
| Crate | Version | Purpose |
|---|---|---|
warp | 0.3 | Core web server framework. |
tokio | 1.0 | Asynchronous runtime. |
serde | 1.0 | Serialization/deserialization of data structures (e.g., ProcessResponse). |
base64 | 0.21 | For encoding and decoding Base64 image data. |
tempfile | 3.0 | To create temporary files for ImageMagick input/output. |
Sources: Cargo.toml:7-13
API Endpoint: POST /upload
This is the only functional endpoint in the application. It accepts URL-encoded form data.
Request Body:
| Parameter | Type | Description |
|---|---|---|
image | String | Base64-encoded image data. |
hdr_value | String | A floating-point number (as a string) representing the HDR intensity. Defaults to 1.5. |
Sources: src/main.rs:16-21
Response Body:
The server responds with a JSON object defined by the ProcessResponse struct.
// Source: src/main.rs:7-12
#[derive(Debug, Serialize)]
struct ProcessResponse {
success: bool,
message: String,
image_data: Option<String>, // base64 encoded HDR image
}
Sources: src/main.rs:7-12
Server Logic (handle_upload)
The handle_upload async function contains the core business logic. The process is as follows:
This flowchart details the step-by-step logic inside the handle_upload function.
Sources: src/main.rs:16-125
Image Processing Pipeline
The application's core value comes from the specific ImageMagick command used to transform the image. This pipeline is executed for every valid request.
The command executed is:
magick <input> -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>
This diagram breaks down the ImageMagick processing steps.
Sources: src/main.rs:81-96, README.md:33-39
Summary
The hdrify project is a well-defined, single-purpose web application that effectively combines a robust Rust backend with a responsive vanilla JavaScript frontend to provide a user-friendly tool for HDR image conversion. Its architecture is straightforward, relying on the power of ImageMagick for the core processing while providing a modern web interface for interaction. The use of client-side caching and smooth UI transitions demonstrates attention to user experience.
Sources: README.md, src/main.rs, static/script.js