Skip to content

Commit 50d5a27

Browse files
committed
CVAuto: 解决 JSONResponse ` 语法报错,优化代码
1 parent 9488d2f commit 50d5a27

File tree

1 file changed

+111
-109
lines changed
  • APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/cv/apijson

1 file changed

+111
-109
lines changed

APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/cv/apijson/JSONResponse.js

Lines changed: 111 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -2503,121 +2503,123 @@ var JSONResponse = {
25032503

25042504
// Draw bboxes
25052505
var bboxes = JSONResponse.getBboxes(detection) || []
2506-
bboxes?.forEach((item, index) => {
2507-
const isHovered = index === hoverBoxId;
2508-
const visible = ! visiblePaths || visiblePaths.length <= 0 || visiblePaths.includes(item.path || item.id);
2509-
if (! visible) {
2510-
return;
2511-
}
2512-
2513-
var [x, y, w, h, d] = JSONResponse.getXYWHD(JSONResponse.getBbox(item) || []);
2514-
const isRate = Math.abs(x) < 1 && Math.abs(y) < 1 && Math.abs(w) < 1 && Math.abs(h) < 1;
2515-
x = isRate ? x*width : x*xRate;
2516-
y = isRate ? y*height : y*yRate;
2517-
w = isRate ? w*width : w*xRate;
2518-
h = isRate ? h*height : h*yRate;
2519-
const angle = item.degree || item.rotate || item.angle || item.perspective || d || 0;
2520-
2521-
var color = item.color;
2522-
if (options.styleOverride) {
2523-
const override = options.styleOverride(item, item['@before']);
2524-
if (override && override.color) {
2525-
color = override.color;
2526-
}
2527-
}
2528-
2529-
const [r, g, b, a] = color || [0, 255, 0, 255];
2530-
const rgba = `rgba(${r}, ${g}, ${b}, ${hoverBoxId != null || ! isHovered ? 0.3 : Math.min(0.5, a < 1 ? a : a / 255)})`;
2531-
2532-
const reversedRgba = `rgba(${255 - r}, ${255 - g}, ${255 - b}`, ${isHovered || hoverBoxId == null ? 1 : 0.3})`;
2533-
// const luma = 0.299 * r + 0.587 * g + 0.114 * b;
2534-
const backgroundFill = rgba; // 还是有些看不清 luma > 186 ? 'rgba(0, 0, 0, 0.5)' : 'rgba(255, 255, 255, 0.5)';
2535-
2536-
ctx.strokeStyle = isHovered ? reversedRgba : rgba;
2537-
ctx.fillStyle = rgba;
2538-
2539-
// Draw horizontal box
2540-
ctx.strokeRect(x, y, w, h);
2541-
2542-
// Optionally draw rotated box
2543-
if (rotateBoxes && angle !== 0) {
2544-
ctx.save();
2545-
ctx.translate(x + w / 2, y + h / 2);
2546-
ctx.rotate((angle * Math.PI) / 180);
2547-
ctx.strokeRect(-w / 2, -h / 2, w, h);
2548-
ctx.restore();
2549-
}
2550-
2551-
if (hoverBoxId != null && ! isHovered) {
2552-
return
2553-
}
2554-
2555-
// Label
2556-
const label = (isDiff ? (item['@before'] ? '- ' : '+ ') : '') + `${item.ocr || item.label || ''}-${item.id || ''} ${((JSONResponse.getScore(item) || 0)*100).toFixed(0)}%${angle == 0 ? '' : ' ' + Math.round(angle) + '°'}`;
2557-
// ctx.font = 'bold 36px';
2558-
// const size = ctx.measureText(label);
2559-
// const textHeight = size.height || height*0.1; // Math.max(height*0.1, size.height);
2560-
// 让字号约为 canvas 高度的 2%,并限定 12~48px
2561-
ctx.font = `bold ${fontSize}px sans-serif`;
2562-
const size = ctx.measureText(label);
2563-
// 自动从 font 里提取 px 字号
2564-
const fontMatch = ctx.font.match(/(\d+)px/);
2565-
const textHeight = fontMatch ? parseInt(fontMatch[1]) : 36; // fallback 到 36px
2566-
const textWidth = size.width; // *textHeight/size.height;
2567-
const padding = 2;
2568-
2569-
let positions = [
2570-
[x, y - textHeight - padding],
2571-
[x + w - textWidth, y - textHeight - padding],
2572-
[x, y + h + padding],
2573-
[x + w - textWidth, y + h + padding]
2574-
];
2575-
2576-
let labelX = x, labelY = y - textHeight - padding;
2577-
for (const [lx, ly] of positions) {
2578-
const overlaps = placedLabels.some(({ x: ox, y: oy, w: ow, h: oh }) =>
2579-
lx < ox + ow && lx + textWidth > ox && ly < oy + oh && ly + textHeight > oy
2580-
);
2581-
if (! overlaps && lx >= 0 && ly >= 0 && lx + textWidth <= canvas.width && ly + textHeight <= canvas.height) {
2582-
labelX = lx;
2583-
labelY = ly;
2584-
break;
2585-
}
2586-
}
2506+
if (bboxes instanceof Array) {
2507+
bboxes?.forEach((item, index) => {
2508+
const isHovered = index === hoverBoxId;
2509+
const visible = ! visiblePaths || visiblePaths.length <= 0 || visiblePaths.includes(item.path || item.id);
2510+
if (! visible) {
2511+
return;
2512+
}
25872513

2588-
placedLabels.push({ x: labelX, y: labelY, w: textWidth, h: textHeight });
2514+
var [x, y, w, h, d] = JSONResponse.getXYWHD(JSONResponse.getBbox(item) || []);
2515+
const isRate = Math.abs(x) < 1 && Math.abs(y) < 1 && Math.abs(w) < 1 && Math.abs(h) < 1;
2516+
x = isRate ? x*width : x*xRate;
2517+
y = isRate ? y*height : y*yRate;
2518+
w = isRate ? w*width : w*xRate;
2519+
h = isRate ? h*height : h*yRate;
2520+
const angle = item.degree || item.rotate || item.angle || item.perspective || d || 0;
2521+
2522+
var color = item.color;
2523+
if (options.styleOverride) {
2524+
const override = options.styleOverride(item, item['@before']);
2525+
if (override && override.color) {
2526+
color = override.color;
2527+
}
2528+
}
25892529

2590-
ctx.save();
2591-
if (rotateText && angle !== 0) {
2592-
ctx.translate(labelX + textWidth / 2, labelY + textHeight / 2);
2593-
ctx.rotate((angle * Math.PI) / 180);
2594-
ctx.translate(-textWidth / 2, -textHeight / 2);
2595-
labelX = 0;
2596-
labelY = 0;
2597-
}
2530+
const [r, g, b, a] = color || [0, 255, 0, 255];
2531+
const rgba = `rgba(${r}, ${g}, ${b}, ${hoverBoxId != null || ! isHovered ? 0.3 : Math.min(0.5, a < 1 ? a : a / 255)})`;
25982532

2599-
if (showLabelBackground) {
2600-
ctx.fillStyle = backgroundFill;
2601-
ctx.fillRect(labelX - 2, labelY - 1, textWidth + 4, textHeight + 2);
2602-
}
2533+
const reversedRgba = `rgba(${255 - r}, ${255 - g}, ${255 - b}, ${isHovered || hoverBoxId == null ? 1 : 0.3})`;
2534+
// const luma = 0.299 * r + 0.587 * g + 0.114 * b;
2535+
const backgroundFill = rgba; // 还是有些看不清 luma > 186 ? 'rgba(0, 0, 0, 0.5)' : 'rgba(255, 255, 255, 0.5)';
26032536

2604-
ctx.fillStyle = showLabelBackground ? reversedRgba : rgba;
2605-
ctx.fillText(label, labelX, labelY);
2606-
ctx.restore();
2537+
ctx.strokeStyle = isHovered ? reversedRgba : rgba;
2538+
ctx.fillStyle = rgba;
26072539

2608-
if (markable && item['@before'] != true) {
2609-
const isWrong = wrongs.indexOf(isDiff ? item['@index'] : index) >= 0; // item.correct === false;
2610-
// 绘制 √ 和 ×
2611-
ctx.font = `bold ${fontSize}px sans-serif`;
2612-
// ctx.fillStyle = isWrong ? 'red' : 'green';
2613-
ctx.fillStyle = isWrong ? 'red' : 'green';
2614-
const checkX = labelX + textWidth + 4;
2615-
const checkY = labelY;
2616-
ctx.fillText(isWrong ? '×' : '√', checkX, checkY);
2617-
}
2540+
// Draw horizontal box
2541+
ctx.strokeRect(x, y, w, h);
26182542

2619-
JSONResponse.drawDetections(canvas, item, options, img, ctx);
2620-
});
2543+
// Optionally draw rotated box
2544+
if (rotateBoxes && angle !== 0) {
2545+
ctx.save();
2546+
ctx.translate(x + w / 2, y + h / 2);
2547+
ctx.rotate((angle * Math.PI) / 180);
2548+
ctx.strokeRect(-w / 2, -h / 2, w, h);
2549+
ctx.restore();
2550+
}
2551+
2552+
if (hoverBoxId != null && ! isHovered) {
2553+
return
2554+
}
2555+
2556+
// Label
2557+
const label = (isDiff ? (item['@before'] ? '- ' : '+ ') : '') + `${item.ocr || item.label || ''}-${item.id || ''} ${((JSONResponse.getScore(item) || 0)*100).toFixed(0)}%${angle == 0 ? '' : ' ' + Math.round(angle) + '°'}`;
2558+
// ctx.font = 'bold 36px';
2559+
// const size = ctx.measureText(label);
2560+
// const textHeight = size.height || height*0.1; // Math.max(height*0.1, size.height);
2561+
// 让字号约为 canvas 高度的 2%,并限定 12~48px
2562+
ctx.font = `bold ${fontSize}px sans-serif`;
2563+
const size = ctx.measureText(label);
2564+
// 自动从 font 里提取 px 字号
2565+
const fontMatch = ctx.font.match(/(\d+)px/);
2566+
const textHeight = fontMatch ? parseInt(fontMatch[1]) : 36; // fallback 到 36px
2567+
const textWidth = size.width; // *textHeight/size.height;
2568+
const padding = 2;
2569+
2570+
let positions = [
2571+
[x, y - textHeight - padding],
2572+
[x + w - textWidth, y - textHeight - padding],
2573+
[x, y + h + padding],
2574+
[x + w - textWidth, y + h + padding]
2575+
];
2576+
2577+
let labelX = x, labelY = y - textHeight - padding;
2578+
for (const [lx, ly] of positions) {
2579+
const overlaps = placedLabels.some(({ x: ox, y: oy, w: ow, h: oh }) =>
2580+
lx < ox + ow && lx + textWidth > ox && ly < oy + oh && ly + textHeight > oy
2581+
);
2582+
if (! overlaps && lx >= 0 && ly >= 0 && lx + textWidth <= canvas.width && ly + textHeight <= canvas.height) {
2583+
labelX = lx;
2584+
labelY = ly;
2585+
break;
2586+
}
2587+
}
2588+
2589+
placedLabels.push({ x: labelX, y: labelY, w: textWidth, h: textHeight });
2590+
2591+
ctx.save();
2592+
if (rotateText && angle !== 0) {
2593+
ctx.translate(labelX + textWidth / 2, labelY + textHeight / 2);
2594+
ctx.rotate((angle * Math.PI) / 180);
2595+
ctx.translate(-textWidth / 2, -textHeight / 2);
2596+
labelX = 0;
2597+
labelY = 0;
2598+
}
2599+
2600+
if (showLabelBackground) {
2601+
ctx.fillStyle = backgroundFill;
2602+
ctx.fillRect(labelX - 2, labelY - 1, textWidth + 4, textHeight + 2);
2603+
}
2604+
2605+
ctx.fillStyle = showLabelBackground ? reversedRgba : rgba;
2606+
ctx.fillText(label, labelX, labelY);
2607+
ctx.restore();
2608+
2609+
if (markable && item['@before'] != true) {
2610+
const isWrong = wrongs.indexOf(isDiff ? item['@index'] : index) >= 0; // item.correct === false;
2611+
// 绘制 √ 和 ×
2612+
ctx.font = `bold ${fontSize}px sans-serif`;
2613+
// ctx.fillStyle = isWrong ? 'red' : 'green';
2614+
ctx.fillStyle = isWrong ? 'red' : 'green';
2615+
const checkX = labelX + textWidth + 4;
2616+
const checkY = labelY;
2617+
ctx.fillText(isWrong ? '×' : '√', checkX, checkY);
2618+
}
2619+
2620+
JSONResponse.drawDetections(canvas, item, options, img, ctx);
2621+
});
2622+
}
26212623

26222624
// Draw lines
26232625
var lines = JSONResponse.getLines(detection);

0 commit comments

Comments
 (0)