Skip to content

🐛(frontend) export any raster image supported by the browser to a PDF#2530

Open
magopian wants to merge 2 commits into
suitenumerique:mainfrom
magopian:fix/image-export-to-pdf
Open

🐛(frontend) export any raster image supported by the browser to a PDF#2530
magopian wants to merge 2 commits into
suitenumerique:mainfrom
magopian:fix/image-export-to-pdf

Conversation

@magopian

@magopian magopian commented Jul 15, 2026

Copy link
Copy Markdown

Fixes #860

Purpose

WebP format isn't supported by react-pdf/renderer and so wasn't exported properly, and some PNG images were also not exporting.

Proposal

First drawing those raster images to a canvas and providing a dataURL to react-pdf/renderer fixes those two bugs at once.

External contributions

Thank you for your contribution! 🎉

Please ensure the following items are checked before submitting your pull request:

General requirements

Skip the checkbox below 👇 if you're fixing an issue or adding documentation

  • Before submitting a PR for a new feature I made sure to contact the product manager

CI requirements

  • I made sure that all existing tests are passing
  • I have signed off my commits with git commit --signoff (DCO compliance)
  • I have signed my commits with my SSH or GPG key (git commit -S)
  • My commit messages follow the required format: <gitmoji>(type) title description
  • I have added a changelog entry under ## [Unreleased] section (if noticeable change)

AI requirements

Skip the checkboxes below 👇 If you didn't use AI for your contribution

  • I used AI assistance to produce part or all of this contribution
  • I have read, reviewed, understood and can explain the code I am submitting
  • I can jump in a call or a chat to explain my work to a maintainer

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 09334fdb-3496-4934-8ef5-ff12880dae27

📥 Commits

Reviewing files that changed from the base of the PR and between b61e00e and 7c2d121.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • src/frontend/apps/e2e/__tests__/app-impress/doc-export.spec.ts
  • src/frontend/apps/impress/src/features/docs/doc-export/__tests__/imagePDF.test.tsx
  • src/frontend/apps/impress/src/features/docs/doc-export/__tests__/utils.test.ts
  • src/frontend/apps/impress/src/features/docs/doc-export/blocks-mapping/imagePDF.tsx
  • src/frontend/apps/impress/src/features/docs/doc-export/utils.ts

Walkthrough

Added raster Blob-to-PNG conversion for PDF export, including canvas resizing and dimension handling. Updated image block mapping to use converted PNG data and handle conversion failures. Added unit tests for conversion and PDF element output, plus an end-to-end regression test confirming PNG content in exported PDFs. Documented the fix in the unreleased changelog.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Suggested reviewers: antolc, ovgodd

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main frontend PDF export change for raster image support.
Description check ✅ Passed The description is directly related to the PDF image export fix and its motivation.
Linked Issues check ✅ Passed The changes address #860 by fixing PNG export handling in the PDF export pipeline.
Out of Scope Changes check ✅ Passed No clear unrelated code changes are present; the utility and test updates support the image export fix.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/frontend/apps/impress/src/features/docs/doc-export/__tests__/imagePDF.test.tsx`:
- Around line 53-66: Update findInTree to use an explicit React element props
type covering children and the src/style fields accessed by its callers, and
apply that type to the return value and relevant casts. Preserve the recursive
traversal while ensuring matched elements expose typed props instead of unknown.

In
`@src/frontend/apps/impress/src/features/docs/doc-export/blocks-mapping/imagePDF.tsx`:
- Around line 28-31: Update the image conversion flow around convertBlobToPng to
catch rejected conversion errors and return the existing empty-image fallback,
View wrap={false}, instead of aborting the PDF export. Preserve the current
handling for undefined results and assign pngConverted and dimensions only after
a successful conversion.

In `@src/frontend/apps/impress/src/features/docs/doc-export/utils.ts`:
- Around line 110-134: Update the image export flow around createImageBitmap and
the canvas operations to wrap getContext, drawImage, and toDataURL in
try/finally, ensuring bmp.close() executes on both success and every failure
path. Preserve the existing sizing and returned PNG behavior, and add a test
covering an exception before the normal return to verify the ImageBitmap is
closed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: a32c5765-abb8-4a96-b09f-8f74f5375317

📥 Commits

Reviewing files that changed from the base of the PR and between 8d2dd5b and 6613e76.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • src/frontend/apps/e2e/__tests__/app-impress/doc-export.spec.ts
  • src/frontend/apps/impress/src/features/docs/doc-export/__tests__/imagePDF.test.tsx
  • src/frontend/apps/impress/src/features/docs/doc-export/__tests__/utils.test.ts
  • src/frontend/apps/impress/src/features/docs/doc-export/blocks-mapping/imagePDF.tsx
  • src/frontend/apps/impress/src/features/docs/doc-export/utils.ts

Comment thread src/frontend/apps/impress/src/features/docs/doc-export/utils.ts Outdated
@magopian
magopian force-pushed the fix/image-export-to-pdf branch from 6613e76 to b61e00e Compare July 15, 2026 15:52

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/frontend/apps/impress/src/features/docs/doc-export/__tests__/imagePDF.test.tsx`:
- Around line 144-147: Update the assertions for the `pdfImage` result in
`imagePDF.test.tsx` to safely access the optional `props.style` before checking
width and height. Use a type-narrowing guard or optional chaining while
preserving the expected values of 450 and 225.

In
`@src/frontend/apps/impress/src/features/docs/doc-export/blocks-mapping/imagePDF.tsx`:
- Around line 34-40: Clamp previewWidth to MAX_WIDTH before invoking
convertSvgToPng or convertBlobToPng in the image conversion try block. Use the
clamped value for canvas allocation while preserving the existing
post-conversion result handling and fallback behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 58f20b77-fd84-4975-9f57-a1b8385c4659

📥 Commits

Reviewing files that changed from the base of the PR and between 6613e76 and b61e00e.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • src/frontend/apps/e2e/__tests__/app-impress/doc-export.spec.ts
  • src/frontend/apps/impress/src/features/docs/doc-export/__tests__/imagePDF.test.tsx
  • src/frontend/apps/impress/src/features/docs/doc-export/__tests__/utils.test.ts
  • src/frontend/apps/impress/src/features/docs/doc-export/blocks-mapping/imagePDF.tsx
  • src/frontend/apps/impress/src/features/docs/doc-export/utils.ts

Comment on lines +144 to +147
const imageEl = findInTree(result as React.ReactNode, 'pdfImage');
expect(imageEl).toBeDefined();
expect(imageEl!.props.style.width).toBe(450);
expect(imageEl!.props.style.height).toBe(225);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

fd -a 'tsconfig*.json' src/frontend/apps/impress src/frontend/apps \
  -x rg -n -C2 '"strict"|"strictNullChecks"' {}

Repository: suitenumerique/docs

Length of output: 535


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the test and the PDF element type definition around the reported lines.
sed -n '1,280p' src/frontend/apps/impress/src/features/docs/doc-export/__tests__/imagePDF.test.tsx

printf '\n----\n'

rg -n "interface PDFElementProps|type PDFElementProps|style\\??:" src/frontend/apps/impress/src/features/docs -S

printf '\n----\n'

# Show surrounding lines for the type definition if found.
TYPE_FILE=$(rg -l "PDFElementProps" src/frontend/apps/impress/src/features/docs -S | head -n 1)
if [ -n "${TYPE_FILE:-}" ]; then
  echo "TYPE_FILE=$TYPE_FILE"
  rg -n -C3 "PDFElementProps|style\\??:" "$TYPE_FILE"
fi

Repository: suitenumerique/docs

Length of output: 12657


Guard the optional style prop in these assertions. PDFElementProps.style is optional, so imageEl!.props.style.width/height fail under the repo’s strict TypeScript config. Narrow style first or use optional chaining in these assertions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/frontend/apps/impress/src/features/docs/doc-export/__tests__/imagePDF.test.tsx`
around lines 144 - 147, Update the assertions for the `pdfImage` result in
`imagePDF.test.tsx` to safely access the optional `props.style` before checking
width and height. Use a type-narrowing guard or optional chaining while
preserving the expected values of 450 and 225.

magopian added 2 commits July 15, 2026 18:10
WebP format isn't supported by react-pdf/renderer and so wasn't exported
properly, and some PNG images were also not exporting.
First drawing those raster images to a canvas and providing a dataURL to
react-pdf/renderer fixes those two bugs at once.

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
@magopian
magopian force-pushed the fix/image-export-to-pdf branch from b61e00e to 7c2d121 Compare July 15, 2026 16:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 PNG export problem

1 participant