How I Built Browser-Based Image Tools Without Uploading User Files
I've used plenty of online image tools over the years. Resize an image. Compress it. Convert WebP to JPG. Convert HEIC to JPG. Turn a few images into a PDF. The workflow is usually simple: Select file → upload it → wait → download the result. But there was always one thing that bothered me: Why does a simple image operation require sending the user's file to a server? For many image-processing…
Online image editing tools often require users to upload their files to a server. This process can be unnecessarily complex and slow. To address this issue, I built Pixyro, a browser-based image tool that performs all operations locally within the user's browser. The design is intentionally simple: users select an image, the browser reads the file, decodes it, processes it in the browser, and finally generates the result which is downloaded by the user. The image never needs to travel to a server.
One of the core components of any image editing tool is the ability to resize, compress, and convert image formats. These tasks can be quite intensive and can cause the user's browser to become unresponsive if the processing is done on the main thread. To avoid this, I utilized Web Workers, which allow heavy processing to be offloaded from the main UI thread. This enables the user interface to remain responsive even when dealing with large images or complex operations.
One of the main challenges in creating a browser-based image tool is that image processing capabilities vary between different web browsers. To ensure reliable performance across all browsers, I relied heavily on the browser's built-in image and canvas APIs. These APIs allow for decoding images into bitmap objects, drawing images onto canvases, and converting the canvas contents back into a Blob (a type of binary data that can be downloaded). These operations can be performed asynchronously using Web Workers, further improving performance.
Another important consideration is that different images have different memory requirements. For instance, a 4000x3000 pixel image can contain over 12 million pixels, each requiring bytes of memory depending on the image format. Processing all of this data directly on the main thread could be slow and resource-intensive. Therefore, I moved the processing into Web Workers whenever possible.
The tool also handles the compression of images to a maximum file size. This is not as straightforward as it might seem because image quality and file size are not directly proportional. For example, a quality setting of 80% does not necessarily result in an image that is 80% of the original size. To address this, I implemented a search strategy that progressively adjusts the image quality until the resulting file size falls within the specified limits.
This approach ensures that the user gets an image that meets their size requirements without compromising too much on quality.
Another consideration is maintaining the aspect ratio of the image. When resizing an image, it is crucial that it does not stretch, crop, or add padding in a way that distorts its original proportions. To achieve this, I calculated a scale factor based on the smaller of the two dimension constraints (width or height) and then applied this factor to both dimensions. This ensures that the image's aspect ratio is preserved.
Finally, modern smartphones often store images with orientation metadata that specifies how the image should be displayed. If this metadata is not accounted for, the image processing tool might misinterpret the image's dimensions and apply incorrect constraints. For example, if an image is stored in a different orientation than it is displayed, the tool might incorrectly apply width and height constraints.
To avoid this, I ensured that the image processing tool accounts for EXIF orientation metadata, ensuring that the image is processed correctly based on how it is intended to be displayed.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.