Compress UV Editor output to avoid 413 Payload Too Large limits on external reverse proxies
This commit is contained in:
@@ -26,8 +26,6 @@ interface UVEditorProps {
|
|||||||
sceneObjects?: any[];
|
sceneObjects?: any[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const CANVAS_SIZE = 1024;
|
|
||||||
|
|
||||||
function deg2rad(d: number) { return d * Math.PI / 180; }
|
function deg2rad(d: number) { return d * Math.PI / 180; }
|
||||||
|
|
||||||
export function UVEditor({ onClose, onSave, targetObject, loadedModel, sceneObjects }: UVEditorProps) {
|
export function UVEditor({ onClose, onSave, targetObject, loadedModel, sceneObjects }: UVEditorProps) {
|
||||||
@@ -50,6 +48,8 @@ export function UVEditor({ onClose, onSave, targetObject, loadedModel, sceneObje
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const saved = targetObject?.materialProps?.uvLayers;
|
const saved = targetObject?.materialProps?.uvLayers;
|
||||||
if (saved?.length) {
|
if (saved?.length) {
|
||||||
|
setCanvasW(1024);
|
||||||
|
setCanvasH(1024);
|
||||||
let n = 0;
|
let n = 0;
|
||||||
const init: Layer[] = saved.map((l: any) => ({ ...l }));
|
const init: Layer[] = saved.map((l: any) => ({ ...l }));
|
||||||
init.forEach(layer => {
|
init.forEach(layer => {
|
||||||
@@ -64,16 +64,27 @@ export function UVEditor({ onClose, onSave, targetObject, loadedModel, sceneObje
|
|||||||
const img = new Image();
|
const img = new Image();
|
||||||
img.crossOrigin = "anonymous";
|
img.crossOrigin = "anonymous";
|
||||||
img.onload = () => {
|
img.onload = () => {
|
||||||
// Automatically scale the image so it fits the 1024x1024 canvas exactly
|
// Reduced MAX size from 2048 to 1024 to prevent huge base64 strings
|
||||||
const scaleX = CANVAS_SIZE / img.width;
|
// that trigger the 1MB Nginx reverse proxy 413 Payload Too Large limit.
|
||||||
const scaleY = CANVAS_SIZE / img.height;
|
const MAX = 1024;
|
||||||
|
let scale = 1;
|
||||||
|
if (img.width > MAX || img.height > MAX) {
|
||||||
|
scale = MAX / Math.max(img.width, img.height);
|
||||||
|
}
|
||||||
|
const cw = Math.round(img.width * scale);
|
||||||
|
const ch = Math.round(img.height * scale);
|
||||||
|
setCanvasW(cw);
|
||||||
|
setCanvasH(ch);
|
||||||
|
|
||||||
|
const scaleX = cw / img.width;
|
||||||
|
const scaleY = ch / img.height;
|
||||||
|
|
||||||
const layer: Layer = {
|
const layer: Layer = {
|
||||||
id: `l-base`,
|
id: `l-base`,
|
||||||
url,
|
url,
|
||||||
img,
|
img,
|
||||||
x: CANVAS_SIZE / 2,
|
x: cw / 2,
|
||||||
y: CANVAS_SIZE / 2,
|
y: ch / 2,
|
||||||
scaleX,
|
scaleX,
|
||||||
scaleY,
|
scaleY,
|
||||||
rotation: 0,
|
rotation: 0,
|
||||||
@@ -109,12 +120,14 @@ export function UVEditor({ onClose, onSave, targetObject, loadedModel, sceneObje
|
|||||||
ctx.restore();
|
ctx.restore();
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
return c.toDataURL(transparent ? 'image/png' : 'image/jpeg');
|
// Use JPEG with 0.75 quality to heavily compress the image size
|
||||||
|
// to avoid hitting the 1MB Nginx reverse proxy limit.
|
||||||
|
return c.toDataURL(transparent ? 'image/png' : 'image/jpeg', 0.75);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Canvas render error (likely CORS taint):", e);
|
console.error("Canvas render error (likely CORS taint):", e);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}, []);
|
}, [canvasW, canvasH]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setPreviewUrl(renderCanvas(layers, bgTransparent, bgColor));
|
setPreviewUrl(renderCanvas(layers, bgTransparent, bgColor));
|
||||||
|
|||||||
Reference in New Issue
Block a user