Skip to content

Bug Report: Different behavior between toPng and toPixelData when devicePixelRatio != 1 results in cropped array #553

@jo-chemla

Description

@jo-chemla

We've come across a case where toPng and toPixelData had different behavior when devicePixelRatio != 1. The image exported using toPng correctly mimics the underlying html DOM div, with rescaled dimensions, but the one exported via toPixelData is cropped because the temporary canvas has screen dimensions.

After digging through, we realized that both exports were identical when devicePixelRatio=1, but having the Windows display scale different than 100%, implied window.devicePixelRatio was eg 150% and resulted in the described bug. Hence, canvas dimensions specified as xml attribute vs those specified as css-style were different, which was probably the origination of this bug. These dimensions were like:

<canvas width="1920" style="width: 1280px; height: 720px;" height="1080" class="mapboxgl-canvas"></canvas>

Expected Behavior

  • toPng dataUrl correctly have rescaled dimensions (not device pixel count 1920, but scaled-down dimension 1280)
  • toPixelData dataArray should have the same rescaled dimensions rather than device dims, even when devicePixelRatio is not unit.

Current Behavior

Currently, toPixelData has wrong dimensions, so one have to use workaround fix by passing options {canvasWidth: width * dpr} to avoid cropping.

Possible Solution

This is a workaround fix, but the behavior should match between toArrayData and toPng/toJpeg etc.
The resolution was passing canvasWidth edited as options to the function call:

dpr = window.devicePixelRatio
toPixelData(parentsDiv, {
  width, 
  canvasWidth: width * dpr, 
  height, 
  canvasHeight: height * dpr, 
})

Steps To Reproduce

This is not a minimal working example, but cloning below repo then, pnpm i && pnpm run dev shows wrong geotiff with toPixelData unless the workaround is passed, but correct non-cropped png when toPng is used.

Additional Context

We have a parentDiv that contains two mapbox-gl map canvases at Iconem/historical-satellite that we wanted to export, and the resulting downloaded image was cropped when using toPixelData, and correct when using toPng.

Your Environment

  • html-to-image: 1.11.11
  • OS: Windows 11
  • Browser: Firefox 140.0.4 and Chrome 138.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions