Skip to content

Commit 51cc26b

Browse files
committed
🐛(frontend) improve svg export to be less pixelized
Some SVGs were pixelized in the exported files. We now add the wanted size to the svg conversion to make sure the images are exported with the correct size and so less pixelized.
1 parent cab8ef5 commit 51cc26b

File tree

3 files changed

+33
-4
lines changed

3 files changed

+33
-4
lines changed

src/frontend/apps/impress/src/features/docs/doc-export/blocks-mapping/imageDocx.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,13 @@ export const blockMappingImageDocx: DocsExporterDocx['mappings']['blockMapping']
2222
let pngConverted: string | undefined;
2323
let dimensions: { width: number; height: number } | undefined;
2424

25+
if (!blob.type.includes('image')) {
26+
return [];
27+
}
28+
2529
if (blob.type.includes('svg')) {
2630
const svgText = await blob.text();
27-
pngConverted = await convertSvgToPng(svgText);
31+
pngConverted = await convertSvgToPng(svgText, block.props.previewWidth);
2832
const img = new Image();
2933
img.src = pngConverted;
3034
await new Promise((resolve) => {

src/frontend/apps/impress/src/features/docs/doc-export/blocks-mapping/imagePDF.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,13 @@ export const blockMappingImagePDF: DocsExporterPDF['mappings']['blockMapping']['
1313
const blob = await exporter.resolveFile(block.props.url);
1414
let pngConverted: string | undefined;
1515

16+
if (!blob.type.includes('image')) {
17+
return <View wrap={false} />;
18+
}
19+
1620
if (blob.type.includes('svg')) {
1721
const svgText = await blob.text();
18-
pngConverted = await convertSvgToPng(svgText);
22+
pngConverted = await convertSvgToPng(svgText, block.props.previewWidth);
1923
}
2024

2125
return (

src/frontend/apps/impress/src/features/docs/doc-export/utils.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,37 @@ export function downloadFile(blob: Blob, filename: string) {
2323
* @param svgText - The SVG text to convert
2424
* @returns The PNG data URL
2525
*/
26-
export async function convertSvgToPng(svgText: string) {
26+
export async function convertSvgToPng(svgText: string, width: number) {
2727
// Create a canvas and render the SVG onto it
2828
const canvas = document.createElement('canvas');
29-
const ctx = canvas.getContext('2d');
29+
const ctx = canvas.getContext('2d', {
30+
alpha: true,
31+
});
3032

3133
if (!ctx) {
3234
throw new Error('Canvas context is null');
3335
}
3436

37+
// Parse SVG to get original dimensions
38+
const parser = new DOMParser();
39+
const svgDoc = parser.parseFromString(svgText, 'image/svg+xml');
40+
const svgElement = svgDoc.documentElement;
41+
42+
// Get viewBox or fallback to width/height attributes
43+
let height;
44+
const svgWidth = svgElement.getAttribute?.('width');
45+
const svgHeight = svgElement.getAttribute?.('height');
46+
const viewBox = svgElement.getAttribute('viewBox')?.split(' ').map(Number);
47+
48+
const originalWidth = svgWidth ? parseInt(svgWidth) : viewBox?.[2];
49+
const originalHeight = svgHeight ? parseInt(svgHeight) : viewBox?.[3];
50+
if (originalWidth && originalHeight) {
51+
const aspectRatio = originalHeight / originalWidth;
52+
height = Math.round(width * aspectRatio);
53+
}
54+
3555
const svg = Canvg.fromString(ctx, svgText);
56+
svg.resize(width, height, true);
3657
await svg.render();
3758

3859
return canvas.toDataURL('image/png');

0 commit comments

Comments
 (0)