The preview looked flawless. A soft vintage filter across a 6000px poster, edges clean, the gradient smooth all the way down. Then I exported, opened the PNG at 100%, and there were faint vertical seams running through the image — thin bands where the tone shifted by a hair. The preview had never shown them. That gap between what you see and what you get turns out to be a consequence of how a browser has to do this, not a defect you can file a ticket against.
A canvas editor running in the browser faces a hard limit a desktop app mostly ignores: memory. Online Design (imging.ai) lets you build up to 8192px on a side, roughly 48 million pixels, across as many as 24 layers, all of it client-side with nothing uploaded. Holding every layer at full resolution while you drag a slider would stall the tab, so the preview you interact with is deliberately rendered at a reduced resolution that fits your viewport, not the full canvas.
When you nudge a filter — one of 12 presets or the 18 fine adjustments — it runs against that downscaled buffer. It is fast and it looks correct, because at screen size the output is visually identical to the full-resolution version. The moment you export, the tool throws the preview away and recomposes the filter against the original full canvas. Different pixel grid, different sampling, and any artifact that only exists at native resolution now has room to appear.
So where do the seams come from? At full resolution a single 48-megapixel filter pass can exceed what the browser will allocate in one block. High-resolution filtering is therefore done in strips: the canvas is sliced into horizontal bands, each processed and written back in turn. If each band is filtered in complete isolation, a filter that samples neighbouring pixels — blur, sharpen, anything with a convolution kernel — has nothing to read at the band's edge, and the two sides of the cut end up computed from slightly different neighbourhoods. That mismatch along the cut is the seam.
The fix is to give each strip an overlap. Every band is expanded by a margin on the shared edge, filtered with that margin present so the kernel always has real neighbours to sample, and then the margin is trimmed before the band is stitched back into place. The seam disappears because the pixels along the cut were computed with the same surrounding context on both sides. The preview never needed any of this — it fit in one buffer — which is exactly why the artifact showed up only on export.
If you want to reproduce and check this deliberately, the flow is short. Create a canvas at the size you actually intend to export, importing a preset shape or a custom dimension. Import your image as a layer, then apply the filter either to that single layer or to the whole canvas. Export as PNG or WebP, and open the result at 100% and, more importantly, at 400%. The preview is a proxy; the exported file is the truth. If they disagree, you are looking at a resolution or stitching issue, not a colour one.
One thing that made this painless to debug: the edit is non-destructive. The filter is stored as parameters, the original pixels are never re-encoded, and the project saves to a .imging file you can reopen and re-tune. I dialled the same filter up and down a dozen times comparing exports without ever degrading the source, which is the only reason isolating the strip behaviour was quick rather than a day of re-importing.
The lesson I took away is boring but reliable: judge a browser image tool by its export at full zoom, never by its preview. The preview is optimised to be fast and to look correct at screen size. Everything that only surfaces at native resolution — banding, seams, softening — lives in the gap between the two, and that gap is where the actual engineering has to happen.

Top comments (0)