Vizan Deployer commited on
Commit ยท
1d196f6
1
Parent(s): b444d61
Add WebP support, update Preview script placement
Browse files- vizan_studio_v2/app.py +94 -42
vizan_studio_v2/app.py
CHANGED
|
@@ -276,7 +276,7 @@ if st.session_state['v2_state'] == 'welcome':
|
|
| 276 |
st.title("๐จ Vizan Designer Studio v2.0")
|
| 277 |
st.write("Professional Carbon-Copy Document Designer")
|
| 278 |
|
| 279 |
-
up = st.file_uploader("Upload Document Image", type=['png', 'jpg', 'jpeg'])
|
| 280 |
if up:
|
| 281 |
f_bytes = np.asarray(bytearray(up.read()), dtype=np.uint8)
|
| 282 |
img = cv2.imdecode(f_bytes, 1)
|
|
@@ -293,9 +293,8 @@ elif st.session_state['v2_state'] == 'studio':
|
|
| 293 |
studio_html = get_designer_v2(d['ocr'], d['image'], d['w'], d['h'])
|
| 294 |
html(studio_html, height=900, scrolling=False)
|
| 295 |
|
| 296 |
-
|
| 297 |
-
|
| 298 |
-
st.subheader("๐ Edit Text & Regenerate Document")
|
| 299 |
|
| 300 |
# --- ACTION BUTTONS & PREVIEW ---
|
| 301 |
st.markdown("---")
|
|
@@ -389,51 +388,104 @@ elif st.session_state['v2_state'] == 'studio':
|
|
| 389 |
# Since these might not be loaded in the main app context (outside get_designer_v2), we reinject them here just in case.
|
| 390 |
# But script tags in st.markdown work.
|
| 391 |
|
| 392 |
-
toolbar_html =
|
| 393 |
-
|
| 394 |
-
|
| 395 |
-
|
| 396 |
-
|
| 397 |
-
|
|
|
|
| 398 |
|
| 399 |
js_logic = """
|
| 400 |
-
|
| 401 |
-
|
| 402 |
-
|
| 403 |
-
|
| 404 |
-
|
| 405 |
-
|
| 406 |
-
|
| 407 |
-
|
| 408 |
-
|
| 409 |
-
|
| 410 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 411 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 412 |
|
| 413 |
-
|
| 414 |
-
|
| 415 |
-
|
| 416 |
-
|
| 417 |
-
|
| 418 |
-
|
| 419 |
-
|
| 420 |
-
|
| 421 |
-
|
| 422 |
-
|
| 423 |
-
|
| 424 |
-
|
| 425 |
-
|
| 426 |
-
|
| 427 |
-
|
| 428 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 429 |
|
| 430 |
st.markdown(
|
| 431 |
f'''
|
| 432 |
-
|
| 433 |
-
|
| 434 |
-
|
| 435 |
-
|
| 436 |
-
|
| 437 |
''',
|
| 438 |
unsafe_allow_html=True
|
| 439 |
)
|
|
|
|
| 276 |
st.title("๐จ Vizan Designer Studio v2.0")
|
| 277 |
st.write("Professional Carbon-Copy Document Designer")
|
| 278 |
|
| 279 |
+
up = st.file_uploader("Upload Document Image", type=['png', 'jpg', 'jpeg', 'webp'])
|
| 280 |
if up:
|
| 281 |
f_bytes = np.asarray(bytearray(up.read()), dtype=np.uint8)
|
| 282 |
img = cv2.imdecode(f_bytes, 1)
|
|
|
|
| 293 |
studio_html = get_designer_v2(d['ocr'], d['image'], d['w'], d['h'])
|
| 294 |
html(studio_html, height=900, scrolling=False)
|
| 295 |
|
| 296 |
+
|
| 297 |
+
# --- ACTION BUTTONS & PREVIEW ---
|
|
|
|
| 298 |
|
| 299 |
# --- ACTION BUTTONS & PREVIEW ---
|
| 300 |
st.markdown("---")
|
|
|
|
| 388 |
# Since these might not be loaded in the main app context (outside get_designer_v2), we reinject them here just in case.
|
| 389 |
# But script tags in st.markdown work.
|
| 390 |
|
| 391 |
+
toolbar_html = """
|
| 392 |
+
<div style="margin-bottom: 10px; display: flex; gap: 10px;">
|
| 393 |
+
<button id="btn-png" style="padding: 5px 10px; cursor: pointer; background: #007bff; color: white; border: none; border-radius: 4px;">๐ผ๏ธ Download PNG</button>
|
| 394 |
+
<button id="btn-pdf" style="padding: 5px 10px; cursor: pointer; background: #dc3545; color: white; border: none; border-radius: 4px;">๐ Download PDF</button>
|
| 395 |
+
</div>
|
| 396 |
+
<div id="js-status" style="font-size: 10px; color: gray; margin-bottom: 5px;"></div>
|
| 397 |
+
"""
|
| 398 |
|
| 399 |
js_logic = """
|
| 400 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
|
| 401 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
|
| 402 |
+
<script>
|
| 403 |
+
window.downloadPreviewImage = function() {
|
| 404 |
+
const status = document.getElementById('js-status');
|
| 405 |
+
if(status) status.innerText = "Status: Starting Image Download...";
|
| 406 |
+
|
| 407 |
+
const element = document.getElementById('preview-container');
|
| 408 |
+
if (!element) { alert('Preview container not found.'); return; }
|
| 409 |
+
|
| 410 |
+
const btn = document.getElementById('btn-png');
|
| 411 |
+
if(btn) btn.innerText = "Processing...";
|
| 412 |
+
|
| 413 |
+
html2canvas(element, { scale: 2 }).then(canvas => {
|
| 414 |
+
try {
|
| 415 |
+
const link = document.createElement('a');
|
| 416 |
+
link.download = 'document_preview.png';
|
| 417 |
+
link.href = canvas.toDataURL();
|
| 418 |
+
link.click();
|
| 419 |
+
if(btn) btn.innerText = "๐ผ๏ธ Download PNG";
|
| 420 |
+
if(status) status.innerText = "Status: Image Done!";
|
| 421 |
+
} catch (e) {
|
| 422 |
+
alert("Error saving image: " + e.message);
|
| 423 |
+
if(btn) btn.innerText = "Error (Try Again)";
|
| 424 |
+
if(status) status.innerText = "Status: Error " + e.message;
|
| 425 |
}
|
| 426 |
+
}).catch(err => {
|
| 427 |
+
alert("html2canvas Error: " + err);
|
| 428 |
+
if(btn) btn.innerText = "Error (Try Again)";
|
| 429 |
+
if(status) status.innerText = "Status: Lib Error " + err;
|
| 430 |
+
});
|
| 431 |
+
};
|
| 432 |
+
|
| 433 |
+
window.downloadPreviewPDF = async function() {
|
| 434 |
+
const status = document.getElementById('js-status');
|
| 435 |
+
if(status) status.innerText = "Status: Starting PDF Download...";
|
| 436 |
+
|
| 437 |
+
const element = document.getElementById('preview-container');
|
| 438 |
+
if (!element) { alert('Preview container not found.'); return; }
|
| 439 |
+
|
| 440 |
+
const btn = document.getElementById('btn-pdf');
|
| 441 |
+
if(btn) btn.innerText = "Processing...";
|
| 442 |
+
|
| 443 |
+
if (!window.html2canvas || !window.jspdf) {
|
| 444 |
+
alert('Libraries not loaded yet. Please wait a few seconds.');
|
| 445 |
+
if(status) status.innerText = "Status: Libraries Loading...";
|
| 446 |
+
return;
|
| 447 |
+
}
|
| 448 |
+
|
| 449 |
+
try {
|
| 450 |
+
const canvas = await html2canvas(element, { scale: 2, useCORS: true });
|
| 451 |
+
const imgData = canvas.toDataURL('image/png');
|
| 452 |
|
| 453 |
+
const { jsPDF } = window.jspdf;
|
| 454 |
+
const pdf = new jsPDF('p', 'mm', 'a4');
|
| 455 |
+
const imgProps = pdf.getImageProperties(imgData);
|
| 456 |
+
const pdfWidth = pdf.internal.pageSize.getWidth();
|
| 457 |
+
const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
|
| 458 |
+
|
| 459 |
+
pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight);
|
| 460 |
+
pdf.save("document_preview.pdf");
|
| 461 |
+
if(btn) btn.innerText = "๐ Download PDF";
|
| 462 |
+
if(status) status.innerText = "Status: PDF Done!";
|
| 463 |
+
} catch (e) {
|
| 464 |
+
alert("Error generating PDF: " + e.message);
|
| 465 |
+
if(btn) btn.innerText = "Error (Try Again)";
|
| 466 |
+
if(status) status.innerText = "Status: Error " + e.message;
|
| 467 |
+
}
|
| 468 |
+
};
|
| 469 |
+
|
| 470 |
+
// Attach listeners explicitly
|
| 471 |
+
const btnPng = document.getElementById('btn-png');
|
| 472 |
+
if(btnPng) {
|
| 473 |
+
btnPng.onclick = window.downloadPreviewImage;
|
| 474 |
+
}
|
| 475 |
+
const btnPdf = document.getElementById('btn-pdf');
|
| 476 |
+
if(btnPdf) {
|
| 477 |
+
btnPdf.onclick = window.downloadPreviewPDF;
|
| 478 |
+
}
|
| 479 |
+
</script>
|
| 480 |
+
"""
|
| 481 |
|
| 482 |
st.markdown(
|
| 483 |
f'''
|
| 484 |
+
{toolbar_html}
|
| 485 |
+
<div id="preview-container" style="position:relative; width:{target_w}px; height:{target_h}px; background:white; color:black; border:1px solid #ddd; box-shadow: 0 4px 8px rgba(0,0,0,0.1); margin: 0 auto; overflow:hidden;">
|
| 486 |
+
{preview_html}
|
| 487 |
+
</div>
|
| 488 |
+
{js_logic}
|
| 489 |
''',
|
| 490 |
unsafe_allow_html=True
|
| 491 |
)
|