Real-time Preview and Processing
Relevant source files
The following files were used as context for generating this wiki page:The Real-time Preview and Processing system is a core feature of HDRify, providing users with immediate visual feedback as they convert SDR images to HDR. It combines a responsive frontend interface with a powerful backend processing pipeline to create an intuitive and efficient user experience. The system is designed to handle image uploads, parameter adjustments via a slider, and display the resulting HDR image with minimal delay.
The frontend is built with vanilla JavaScript, HTML, and CSS, managing the user interface state and interactions. The backend is a Rust application using the warp web server framework, which exposes a single API endpoint to handle the image processing logic via the ImageMagick command-line tool.
Sources: README.md:3-5, static/script.js, src/main.rs
Architecture Overview
The system is composed of a client-side component running in the user's browser and a server-side component that performs the heavy lifting of image manipulation. The user interacts with the frontend, which then communicates with the backend via an API call. The backend processes the image and returns the result, which the frontend then displays.
This diagram illustrates the high-level architecture of the real-time processing system.
Sources: static/script.js, src/main.rs, README.md:43-46
Frontend Implementation
The entire frontend logic for real-time interaction is encapsulated within the HDRify JavaScript class. This class manages the application's state, handles all user events, and orchestrates the communication with the backend.
Sources: static/script.js:1-3
UI Components
The user interface is defined in index.html and consists of several key elements that the HDRify class interacts with.
| Element ID | Description | Source File |
|---|---|---|
uploadArea | The initial drag-and-drop area for image uploads. | static/index.html:25 |
imageInput | A hidden file input field, triggered by clicks on uploadArea. | static/index.html:28 |
imageDisplay | A container for the processed image preview that appears after an upload. | static/index.html:32 |
resultImage | The <img> element that displays the original and processed images. | static/index.html:33 |
processingOverlay | A spinner overlay shown during backend processing. | static/index.html:34 |
controls | A container for the HDR slider, download, and reset buttons. | static/index.html:41 |
hdrSlider | The range input slider (0.5 to 3.0) for adjusting the HDR intensity. | static/index.html:44 |
resetButton | A button to reset the interface to its initial state. | static/index.html:49 |
The HDRify Class
The HDRify class is the central controller for the frontend. It initializes element references and sets up all necessary event listeners.
This diagram shows the structure of the HDRify class, including its properties and key methods.
Sources: static/script.js:1-10
State Management and Caching
To provide a fast and responsive experience, the frontend employs two key strategies: state management and caching.
- State: The
HDRifyclass instance holds the current state, including the base64-encoded original image (currentImageData), its data URL (originalImageUrl), and the original filename (originalFileName). - Caching: A
MapnamedimageCacheis used to store the base64 data of already processed images. The cache key is the HDR value (e.g.,"1.5"). When the user adjusts the slider to a previously used value, the image is loaded directly from the cache, avoiding a redundant API call.
Sources: static/script.js:2-6, static/script.js:248-261
Event Handling and Processing Flow
The user journey from uploading an image to seeing the processed result is managed by a series of event listeners.
- Upload: The user can either click the
uploadAreaor drag and drop a file onto it. This triggers thehandleFilemethod. - Validation:
handleFileperforms client-side validation for file type (JPEG, PNG, WebP) and size (max 10MB). - Initial Processing: If the file is valid, it's read as a
DataURL. ThetransitionToImageViewmethod is called to animate the UI from the upload view to the image preview. The initial image is shown with a heavy blur effect while the first processing request is sent. - Slider Interaction: When the
hdrSlidervalue changes, aninputevent is fired. To prevent excessive API calls, theprocessImagefunction is debounced with a 250ms timeout. - API Call: The
processImagefunction sends the original image data and the current HDR value to the/uploadbackend endpoint. - Display: Upon a successful response, the
resultImagesrcis updated with the new base64 image data, the blur filter is removed, and the result is stored inimageCache.
This sequence diagram details the frontend interaction flow.
Backend Implementation
The backend is a lightweight Rust server built with warp. It exposes a single endpoint responsible for receiving image data, processing it with ImageMagick, and returning the result.
Sources: src/main.rs, Cargo.toml:7-14
API Endpoint: POST /upload
The server listens for POST requests on the /upload path. It expects URL-encoded form data.
Request Body (application/x-www-form-urlencoded)
| Parameter | Type | Description | Required |
|---|---|---|---|
image | String | Base64-encoded image data (without the data: prefix). | Yes |
hdr_value | Float | The HDR intensity value (e.g., 1.5). Defaults to 1.5. | No |
Sources: src/main.rs:16-21, static/script.js:289-291
Response Body (application/json)
The server returns a JSON object indicating the outcome.
{
"success": true,
"message": "Image processed successfully",
"image_data": "base64_encoded_hdr_image_string"
}
Sources: src/main.rs:9-13, src/main.rs:101-105
Processing Logic in handle_upload
The handle_upload async function contains the core backend logic.
This flowchart shows the step-by-step logic inside the handle_upload function.
Sources: src/main.rs:15-128
ImageMagick Pipeline
The actual image conversion is delegated to the ImageMagick magick command-line tool. The backend constructs and executes a specific pipeline of operations derived from the guide at sharpletters.net.
| Argument | Purpose |
|---|---|
-define quantum:format | Use floating-point precision for color values. |
-colorspace RGB | Convert to a linear RGB colorspace. |
-auto-gamma | Apply automatic gamma correction. |
-evaluate Multiply X | Multiply brightness by the user-provided hdr_value. |
-evaluate Pow 0.9 | Apply a power curve adjustment. |
-colorspace sRGB | Convert back to the sRGB colorspace. |
-depth 16 | Set the bit depth to 16 bits per channel. |
-profile 2020_profile.icc | Apply the Rec. 2020 color profile to mark it as an HDR image. |
Sources: src/main.rs:82-96, README.md:28-35
Conclusion
The Real-time Preview and Processing system in HDRify is a well-architected feature that balances client-side responsiveness with server-side processing power. The frontend HDRify class effectively manages UI state and user interactions, using debouncing and caching to ensure a smooth experience. On the backend, a minimal Rust and warp server provides a robust API that securely validates input and leverages the proven capabilities of ImageMagick for high-quality HDR conversion. This separation of concerns results in an efficient, interactive, and user-friendly application.
Sources: static/script.js, src/main.rs