fix(vwb): capture plein écran + auto-détection MIME PNG/JPEG des ancres
Some checks failed
security-audit / Bandit (scan statique) (push) Successful in 12s
security-audit / pip-audit (CVE dépendances) (push) Successful in 10s
security-audit / Scan secrets (grep) (push) Successful in 8s
tests / Lint (ruff + black) (push) Successful in 12s
tests / Tests unitaires (sans GPU) (push) Failing after 13s
tests / Tests sécurité (critique) (push) Has been skipped
Some checks failed
security-audit / Bandit (scan statique) (push) Successful in 12s
security-audit / pip-audit (CVE dépendances) (push) Successful in 10s
security-audit / Scan secrets (grep) (push) Successful in 8s
tests / Lint (ruff + black) (push) Successful in 12s
tests / Tests unitaires (sans GPU) (push) Failing after 13s
tests / Tests sécurité (critique) (push) Has been skipped
- CSS fullscreen-content : height:0 + min-height:0 pour forcer flex fill - Image fullscreen : max-height calc(100vh - 60px) + object-fit contain - Fonction b64ImgSrc() détecte automatiquement PNG vs JPEG depuis le base64 - Corrige l'affichage des thumbnails compressés JPEG dans la bibliothèque - Appliqué dans CapturePanel + CaptureLibrary (toutes les occurrences) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,12 @@ import {
|
|||||||
compressThumbnail,
|
compressThumbnail,
|
||||||
} from '../services/captureLibraryStorage';
|
} from '../services/captureLibraryStorage';
|
||||||
|
|
||||||
|
function b64ImgSrc(base64: string): string {
|
||||||
|
if (base64.startsWith('data:')) return base64;
|
||||||
|
const mime = base64.startsWith('/9j/') ? 'image/jpeg' : 'image/png';
|
||||||
|
return `data:${mime};base64,${base64}`;
|
||||||
|
}
|
||||||
|
|
||||||
interface LibraryItem {
|
interface LibraryItem {
|
||||||
id: string;
|
id: string;
|
||||||
capture: Capture;
|
capture: Capture;
|
||||||
@@ -149,7 +155,7 @@ export default function CaptureLibrary({ currentCapture, onSelectCapture, onCapt
|
|||||||
{!isExpanded && currentCapture && (
|
{!isExpanded && currentCapture && (
|
||||||
<div className="library-preview">
|
<div className="library-preview">
|
||||||
<img
|
<img
|
||||||
src={`data:image/png;base64,${currentCapture.screenshot_base64}`}
|
src={{b64ImgSrc(currentCapture.screenshot_base64)}}
|
||||||
alt="Dernière capture"
|
alt="Dernière capture"
|
||||||
onClick={() => setIsExpanded(true)}
|
onClick={() => setIsExpanded(true)}
|
||||||
/>
|
/>
|
||||||
@@ -209,7 +215,7 @@ export default function CaptureLibrary({ currentCapture, onSelectCapture, onCapt
|
|||||||
className={`library-item ${selectedItems.has(item.id) ? 'selected' : ''}`}
|
className={`library-item ${selectedItems.has(item.id) ? 'selected' : ''}`}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src={`data:image/png;base64,${item.capture.screenshot_base64}`}
|
src={{b64ImgSrc(item.capture.screenshot_base64)}}
|
||||||
alt="Capture"
|
alt="Capture"
|
||||||
onClick={() => onSelectCapture(item.capture)}
|
onClick={() => onSelectCapture(item.capture)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -7,6 +7,12 @@ import {
|
|||||||
compressThumbnail,
|
compressThumbnail,
|
||||||
} from '../services/captureLibraryStorage';
|
} from '../services/captureLibraryStorage';
|
||||||
|
|
||||||
|
function b64ImgSrc(base64: string): string {
|
||||||
|
if (base64.startsWith('data:')) return base64;
|
||||||
|
const mime = base64.startsWith('/9j/') ? 'image/jpeg' : 'image/png';
|
||||||
|
return `data:${mime};base64,${base64}`;
|
||||||
|
}
|
||||||
|
|
||||||
interface DetectionZone {
|
interface DetectionZone {
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
@@ -106,7 +112,7 @@ export default function CapturePanel({
|
|||||||
try {
|
try {
|
||||||
const { detectUIElements } = await import('../services/uiDetection');
|
const { detectUIElements } = await import('../services/uiDetection');
|
||||||
const result = await detectUIElements(
|
const result = await detectUIElements(
|
||||||
`data:image/png;base64,${currentCapture.screenshot_base64}`,
|
{b64ImgSrc(currentCapture.screenshot_base64)},
|
||||||
{ threshold: 0.35 }
|
{ threshold: 0.35 }
|
||||||
);
|
);
|
||||||
setPreviewElements(result.elements);
|
setPreviewElements(result.elements);
|
||||||
@@ -211,7 +217,7 @@ export default function CapturePanel({
|
|||||||
<div className="capture-preview-container">
|
<div className="capture-preview-container">
|
||||||
<img
|
<img
|
||||||
ref={previewImgRef}
|
ref={previewImgRef}
|
||||||
src={`data:image/png;base64,${currentCapture.screenshot_base64}`}
|
src={{b64ImgSrc(currentCapture.screenshot_base64)}}
|
||||||
alt="Capture"
|
alt="Capture"
|
||||||
onClick={() => setIsFullscreen(true)}
|
onClick={() => setIsFullscreen(true)}
|
||||||
onLoad={handlePreviewImageLoad}
|
onLoad={handlePreviewImageLoad}
|
||||||
@@ -274,7 +280,7 @@ export default function CapturePanel({
|
|||||||
{library.slice(0, 4).map(item => (
|
{library.slice(0, 4).map(item => (
|
||||||
<div key={item.id} className="library-item">
|
<div key={item.id} className="library-item">
|
||||||
<img
|
<img
|
||||||
src={`data:image/png;base64,${item.capture.screenshot_base64}`}
|
src={{b64ImgSrc(item.capture.screenshot_base64)}}
|
||||||
alt="Capture"
|
alt="Capture"
|
||||||
onClick={() => handleLibrarySelect(item)}
|
onClick={() => handleLibrarySelect(item)}
|
||||||
/>
|
/>
|
||||||
@@ -315,7 +321,7 @@ export default function CapturePanel({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src={`data:image/png;base64,${item.capture.screenshot_base64}`}
|
src={{b64ImgSrc(item.capture.screenshot_base64)}}
|
||||||
alt="Capture"
|
alt="Capture"
|
||||||
/>
|
/>
|
||||||
<div className="library-gallery-label">
|
<div className="library-gallery-label">
|
||||||
@@ -382,7 +388,7 @@ function FullscreenSelector({
|
|||||||
try {
|
try {
|
||||||
const { detectUIElements } = await import('../services/uiDetection');
|
const { detectUIElements } = await import('../services/uiDetection');
|
||||||
const result = await detectUIElements(
|
const result = await detectUIElements(
|
||||||
`data:image/png;base64,${capture.screenshot_base64}`,
|
b64ImgSrc(capture.screenshot_base64),
|
||||||
{ threshold: 0.35 }
|
{ threshold: 0.35 }
|
||||||
);
|
);
|
||||||
setDetectedElements(result.elements);
|
setDetectedElements(result.elements);
|
||||||
@@ -538,14 +544,14 @@ function FullscreenSelector({
|
|||||||
onMouseUp={handleMouseUp}
|
onMouseUp={handleMouseUp}
|
||||||
>
|
>
|
||||||
{/* Conteneur relatif pour positionner les bboxes et la sélection par rapport à l'image */}
|
{/* Conteneur relatif pour positionner les bboxes et la sélection par rapport à l'image */}
|
||||||
<div style={{ position: 'relative', display: 'inline-block' }}>
|
<div style={{ position: 'relative', display: 'inline-block', maxWidth: '100%', maxHeight: '100%' }}>
|
||||||
<img
|
<img
|
||||||
ref={imgRef}
|
ref={imgRef}
|
||||||
src={`data:image/png;base64,${capture.screenshot_base64}`}
|
src={{b64ImgSrc(capture.screenshot_base64)}}
|
||||||
alt="Capture plein écran"
|
alt="Capture plein écran"
|
||||||
draggable={false}
|
draggable={false}
|
||||||
onLoad={handleImageLoad}
|
onLoad={handleImageLoad}
|
||||||
style={{ display: 'block' }}
|
style={{ display: 'block', maxWidth: '100%', maxHeight: 'calc(100vh - 60px)', objectFit: 'contain' }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Overlay des éléments détectés — visible dans tous les modes */}
|
{/* Overlay des éléments détectés — visible dans tous les modes */}
|
||||||
|
|||||||
@@ -1079,11 +1079,16 @@ body {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
height: 0;
|
||||||
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fullscreen-content img {
|
.fullscreen-content img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
object-fit: contain;
|
||||||
cursor: crosshair;
|
cursor: crosshair;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user