Repository navigation
Draw zoomed-in image pixels as sharp blocks - #75
Merged
Merged
Conversation
Since the uniform-image bitmap became a Plotly layout image (v0.6.1), the browser smoothed it whenever it was enlarged: zoomed-in pixels faded into each other, unlike DataLab desktop (nearest pixel by default) and unlike the former image trace (pixelated style, magnified canvas on Safari and in exports). - the raster plan magnifies each painted cell by integer factors when zoomed in (from two device pixels per image pixel, within the bitmap size cap); the window is painted 1:1 as before, then copied onto the magnified canvas without smoothing, so pixels are sharp blocks in every browser and in exported PNG images; small images are magnified whole when they fit, so panning never uncovers unpainted areas; - the views set image-rendering: pixelated on their layout images only while the bitmap shows undecimated pixels enlarged on screen, so the remaining enlargement stays sharp without aliasing reduced or decimated bitmaps (spatial view: when every visible bitmap qualifies; processing preview, whose plot size is not tracked: when the bitmap is magnified); - the placement of the bitmap is unchanged (physical cell size). Refs #74 Assisted-by: Claude Opus 5.5
Refs #74 Assisted-by: Claude Opus 5.5
Contributor
Author
|
CI does not trigger automatically on a PR stacked on another branch: the full \ ests\ workflow was dispatched on \ix/image-viewer-crisp-pixels\ and passed (vitest, pytest 3.11/3.12, the 4 Playwright shards): https://github.com/DataLab-Platform/web/actions/runs/40203589859 |
PierreRaybaut
changed the base branch from
fix/image-viewer-pixel-centers
to
develop
October 25, 2026 15:02
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #74
Summary
Since v0.6.1 (8d6f1f1), the uniform-image bitmap is a Plotly layout image, which the browser smooths whenever it is enlarged: zoomed-in pixels fade into each other. The former
imagetrace avoided it (zsmooth: false→image-rendering: pixelated, or a magnified canvas on Safari and in exports), and DataLab desktop shows the nearest pixel by default.imageLod.ts,imageRaster.ts): when zoomed in (at least two device pixels per image pixel), the raster plan getszoomX/zoomYfactors (floor(display budget / visible pixels), within the 2048-pixel cap). The window is painted 1:1 as before, then copied onto the magnified canvas withimageSmoothingEnabled = false: every pixel is a sharp block, in every browser and in exported PNG images (modebar download, AI assistant capture). Small images are magnified whole when they fit, so panning never uncovers unpainted areas; otherwise only the visible window is painted, as for large images. The bitmap placement is unchanged (physical cell size).styles.css):image-rendering: pixelated(Plotly's declaration list) on the layout images of a view, set only while its bitmap shows undecimated pixels enlarged on screen (showsCrispPixels). The small remaining enlargement then stays sharp on Chrome, Edge and Firefox. Measured in Chromium:pixelatedalso samples to the nearest pixel when downscaling (a fine checkerboard turns black instead of mid-grey), so it is never set on reduced or decimated bitmaps.Not affected: thumbnails (already
pixelated), non-uniform images and the profile dialog (Plotly heatmaps drawn at screen resolution).Validation
drawImagewithout smoothing, fallback without a 2D context),showsCrispPixels(magnified, slightly enlarged, reduced, decimated, DPR), and the CSS class in the image viewer and the spatial view.image-lod(including a new checkerboard test: integer magnification, a bitmap with exactly two colours, computedimage-rendering: pixelated, and a screen row with only the two colours; the new test fails on the base branch),image-pan,image-roi-drag,multi-image-spatial: 10 passed.Plotly.toImageexport.npm run buildwithin the bundle budget.