Merge pull request #114 from presenton/feat/presentation_export

fix(nextjs): improves parse border radius to clamp
This commit is contained in:
Saurav Niraula 2025-07-21 18:58:20 +05:45 committed by GitHub
commit d9e2f5ab2f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 25 additions and 3 deletions

View file

@ -1,3 +1,4 @@
import asyncio
import json
from fastapi import APIRouter, HTTPException
from fastapi.responses import StreamingResponse

View file

@ -53,6 +53,11 @@ def round_image_corners(image: Image.Image, radii: List[int]) -> Image.Image:
)
w, h = image.size
# Clamp border radius to not exceed half the width or height
max_radius = min(w // 2, h // 2)
clamped_radii = [min(radius, max_radius) for radius in radii]
# Ensure the image has an alpha channel (RGBA)
if image.mode != "RGBA":
image = image.convert("RGBA")
@ -64,7 +69,7 @@ def round_image_corners(image: Image.Image, radii: List[int]) -> Image.Image:
rectangular_mask = Image.new("L", image.size, 255)
# Process each corner
for i, radius in enumerate(radii):
for i, radius in enumerate(clamped_radii):
if radius > 0: # Only process if radius is positive
# Create a circle for this radius
circle = Image.new("L", (radius * 2, radius * 2), 0)

View file

@ -105,6 +105,7 @@ async function postProcessSlidesAttributes(slidesAttributes: SlideAttributesResu
const screenshotPath = await screenshotElement(element, screenshotsDir);
element.imageSrc = screenshotPath;
element.should_screenshot = false;
element.objectFit = 'cover';
element.element = undefined;
}
}
@ -701,7 +702,7 @@ async function getElementAttributes(element: ElementHandle<Element>): Promise<El
: paddingObj;
}
function parseBorderRadius(computedStyles: CSSStyleDeclaration) {
function parseBorderRadius(computedStyles: CSSStyleDeclaration, el: Element) {
const borderRadius = computedStyles.borderRadius;
let borderRadiusValue;
@ -716,6 +717,20 @@ async function getElementAttributes(element: ElementHandle<Element>): Promise<El
} else if (radiusParts.length === 4) {
borderRadiusValue = radiusParts;
}
// Clamp border radius values to be between 0 and half the width/height
if (borderRadiusValue) {
const rect = el.getBoundingClientRect();
const maxRadiusX = rect.width / 2;
const maxRadiusY = rect.height / 2;
borderRadiusValue = borderRadiusValue.map((radius, index) => {
// For top-left and bottom-right corners, use maxRadiusX
// For top-right and bottom-left corners, use maxRadiusY
const maxRadius = (index === 0 || index === 2) ? maxRadiusX : maxRadiusY;
return Math.max(0, Math.min(radius, maxRadius));
});
}
}
return borderRadiusValue;
@ -757,7 +772,7 @@ async function getElementAttributes(element: ElementHandle<Element>): Promise<El
const objectFit = computedStyles.objectFit as 'contain' | 'cover' | 'fill' | undefined;
const imageSrc = (el as HTMLImageElement).src;
const borderRadiusValue = parseBorderRadius(computedStyles);
const borderRadiusValue = parseBorderRadius(computedStyles, el);
const shape = parseShape(el, borderRadiusValue) as 'rectangle' | 'circle' | undefined;

View file

@ -233,6 +233,7 @@ function convertToPictureBox(element: ElementAttributes): PptxPictureBoxModel {
fit: element.objectFit ? (element.objectFit as PptxObjectFitEnum) : PptxObjectFitEnum.CONTAIN
};
// Extract image path from element attributes
const picture: PptxPictureModel = {
is_network: element.imageSrc ? element.imageSrc.startsWith('http') : false,