@pilio/gemini-watermark-remover 1.0.17 → 1.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -4
- package/README_zh.md +0 -1
- package/package.json +1 -1
- package/src/core/candidateSelector.js +233 -45
- package/src/core/geminiSizeCatalog.js +15 -0
- package/src/core/restorationMetrics.js +166 -0
- package/src/core/watermarkEngine.js +0 -1
- package/src/core/watermarkProcessor.js +765 -107
- package/src/runtime/browser.js +6 -2
- package/src/runtime/userscript.js +8 -2
- package/src/sdk/index.d.ts +0 -1
- package/src/shared/imageProcessing.js +3 -1
- package/src/userscript/processingRuntime.js +4 -3
package/README.md
CHANGED
|
@@ -209,10 +209,9 @@ import {
|
|
|
209
209
|
Use the pure-data API when you already have decoded `ImageData`:
|
|
210
210
|
|
|
211
211
|
```javascript
|
|
212
|
-
const result = await removeWatermarkFromImageData(imageData, {
|
|
213
|
-
adaptiveMode: 'auto',
|
|
214
|
-
|
|
215
|
-
});
|
|
212
|
+
const result = await removeWatermarkFromImageData(imageData, {
|
|
213
|
+
adaptiveMode: 'auto',
|
|
214
|
+
});
|
|
216
215
|
|
|
217
216
|
console.log(result.meta.decisionTier);
|
|
218
217
|
```
|
package/README_zh.md
CHANGED
package/package.json
CHANGED
|
@@ -31,6 +31,11 @@ const VALIDATION_MAX_GRADIENT_INCREASE = 0.04;
|
|
|
31
31
|
const VALIDATION_MIN_CONFIDENCE_FOR_ADAPTIVE_TRIAL = 0.25;
|
|
32
32
|
const STANDARD_FAST_PATH_RESIDUAL_THRESHOLD = 0.22;
|
|
33
33
|
const STANDARD_FAST_PATH_GRADIENT_THRESHOLD = 0.08;
|
|
34
|
+
const FIXED_CORE_MAX_ACCEPTED_SPATIAL_RESIDUAL = 0.36;
|
|
35
|
+
const STANDARD_EXPAND_CATALOG_MIN_ORIGINAL_GRADIENT = 0.12;
|
|
36
|
+
const WEAK_ALPHA_PRIORITY_CLEAN_GRADIENT_THRESHOLD = 0.12;
|
|
37
|
+
const STRONG_ORIGINAL_SIGNAL_SPATIAL_ADVANTAGE = 0.2;
|
|
38
|
+
const STRONG_ORIGINAL_SIGNAL_GRADIENT_ADVANTAGE = 0.25;
|
|
34
39
|
const STANDARD_NEARBY_SEARCH_RESIDUAL_THRESHOLD = 0.18;
|
|
35
40
|
const STANDARD_NEARBY_SEARCH_GRADIENT_THRESHOLD = 0.05;
|
|
36
41
|
const STANDARD_LOCAL_SHIFT_STRONG_BASE_GRADIENT_SCORE = 0.35;
|
|
@@ -57,6 +62,13 @@ const STANDARD_HARD_REJECT_OVERRIDE_MAX_RESIDUAL = 0.08;
|
|
|
57
62
|
const STANDARD_HARD_REJECT_OVERRIDE_MAX_GRADIENT = 0.1;
|
|
58
63
|
const STANDARD_HARD_REJECT_OVERRIDE_MIN_IMPROVEMENT = 0.7;
|
|
59
64
|
const STANDARD_HARD_REJECT_OVERRIDE_MAX_NEAR_BLACK_INCREASE = 0.01;
|
|
65
|
+
const STANDARD_STRONG_SIGNAL_NEAR_BLACK_OVERRIDE_MIN_SPATIAL_SCORE = 0.9;
|
|
66
|
+
const STANDARD_STRONG_SIGNAL_NEAR_BLACK_OVERRIDE_MIN_GRADIENT_SCORE = 0.7;
|
|
67
|
+
const STANDARD_STRONG_SIGNAL_NEAR_BLACK_OVERRIDE_MAX_RESIDUAL = 0.22;
|
|
68
|
+
const STANDARD_STRONG_SIGNAL_NEAR_BLACK_OVERRIDE_MAX_GRADIENT = 0.32;
|
|
69
|
+
const STANDARD_STRONG_SIGNAL_NEAR_BLACK_OVERRIDE_MIN_IMPROVEMENT = 0.7;
|
|
70
|
+
const STANDARD_STRONG_SIGNAL_NEAR_BLACK_OVERRIDE_MIN_GRADIENT_DROP = 0.6;
|
|
71
|
+
const STANDARD_STRONG_SIGNAL_NEAR_BLACK_OVERRIDE_MAX_NEAR_BLACK_INCREASE = 0.4;
|
|
60
72
|
const TEMPLATE_ALIGN_SHIFTS = [-0.5, -0.25, 0, 0.25, 0.5];
|
|
61
73
|
const TEMPLATE_ALIGN_SCALES = [0.99, 1, 1.01];
|
|
62
74
|
const STANDARD_NEARBY_SHIFTS = [-12, -8, -4, 0, 4, 8, 12];
|
|
@@ -93,6 +105,7 @@ function mergeCandidateProvenance(...provenanceParts) {
|
|
|
93
105
|
|
|
94
106
|
function isProjectedPreviewCatalogConfig(originalImageData, candidateConfig, baseConfig) {
|
|
95
107
|
if (!originalImageData || !candidateConfig) return false;
|
|
108
|
+
if (candidateConfig.fixedVariant === true) return false;
|
|
96
109
|
if (matchOfficialGeminiImageSize(originalImageData.width, originalImageData.height)) return false;
|
|
97
110
|
|
|
98
111
|
return candidateConfig.logoSize < 48 ||
|
|
@@ -165,6 +178,7 @@ function buildStandardCandidateSeeds({
|
|
|
165
178
|
: (candidateConfig === config ? 'standard' : 'standard+catalog'),
|
|
166
179
|
provenance: mergeCandidateProvenance(
|
|
167
180
|
candidateConfig === config ? null : { catalogVariant: true },
|
|
181
|
+
candidateConfig.fixedVariant === true ? { fixedVariant: true } : null,
|
|
168
182
|
projectedPreviewCatalog ? { previewAnchor: true } : null,
|
|
169
183
|
candidateConfig.alphaVariant ? { alphaVariant: candidateConfig.alphaVariant } : null
|
|
170
184
|
)
|
|
@@ -182,15 +196,26 @@ function inferDecisionTier(candidate, { directMatch = false } = {}) {
|
|
|
182
196
|
return 'safe-removal';
|
|
183
197
|
}
|
|
184
198
|
|
|
185
|
-
function shouldEscalateSearch(candidate) {
|
|
186
|
-
if (!candidate) return true;
|
|
187
|
-
|
|
188
|
-
return Math.abs(candidate.processedSpatialScore) > STANDARD_FAST_PATH_RESIDUAL_THRESHOLD ||
|
|
189
|
-
Math.max(0, candidate.processedGradientScore) > STANDARD_FAST_PATH_GRADIENT_THRESHOLD;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
function
|
|
193
|
-
if (!candidate) return true;
|
|
199
|
+
function shouldEscalateSearch(candidate) {
|
|
200
|
+
if (!candidate) return true;
|
|
201
|
+
|
|
202
|
+
return Math.abs(candidate.processedSpatialScore) > STANDARD_FAST_PATH_RESIDUAL_THRESHOLD ||
|
|
203
|
+
Math.max(0, candidate.processedGradientScore) > STANDARD_FAST_PATH_GRADIENT_THRESHOLD;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function shouldExpandCatalogForWeakOriginalStandardEvidence(candidate) {
|
|
207
|
+
if (!candidate) return true;
|
|
208
|
+
if (!isStandardCandidateSource(candidate)) return false;
|
|
209
|
+
if (candidate?.provenance?.catalogVariant === true) return false;
|
|
210
|
+
|
|
211
|
+
const originalGradient = Number(candidate.originalGradientScore);
|
|
212
|
+
if (!Number.isFinite(originalGradient)) return false;
|
|
213
|
+
|
|
214
|
+
return originalGradient < STANDARD_EXPAND_CATALOG_MIN_ORIGINAL_GRADIENT;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function shouldSearchNearbyStandardCandidate(candidate, originalImageData) {
|
|
218
|
+
if (!candidate) return true;
|
|
194
219
|
|
|
195
220
|
return Number(candidate.position?.width) >= 72 &&
|
|
196
221
|
Number(originalImageData?.height) > Number(originalImageData?.width) * 1.25 &&
|
|
@@ -262,6 +287,22 @@ function isCleanStandardAlphaCandidate(candidate) {
|
|
|
262
287
|
Math.max(0, candidate.processedGradientScore) <= STANDARD_FAST_PATH_GRADIENT_THRESHOLD;
|
|
263
288
|
}
|
|
264
289
|
|
|
290
|
+
function isStrictFixedCoreCandidate(candidate) {
|
|
291
|
+
if (!candidate?.accepted) return false;
|
|
292
|
+
|
|
293
|
+
const processedSpatial = Number(candidate.processedSpatialScore);
|
|
294
|
+
if (!Number.isFinite(processedSpatial)) return false;
|
|
295
|
+
|
|
296
|
+
return Math.abs(processedSpatial) <= FIXED_CORE_MAX_ACCEPTED_SPATIAL_RESIDUAL;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function isCleanWeakAlphaPriorityCandidate(candidate) {
|
|
300
|
+
if (!candidate?.accepted) return false;
|
|
301
|
+
|
|
302
|
+
return Math.abs(candidate.processedSpatialScore) <= STANDARD_FAST_PATH_RESIDUAL_THRESHOLD &&
|
|
303
|
+
Math.max(0, candidate.processedGradientScore) <= WEAK_ALPHA_PRIORITY_CLEAN_GRADIENT_THRESHOLD;
|
|
304
|
+
}
|
|
305
|
+
|
|
265
306
|
function normalizeAlphaPriorityGains(alphaPriorityGains) {
|
|
266
307
|
const gains = Array.isArray(alphaPriorityGains) && alphaPriorityGains.length > 0
|
|
267
308
|
? alphaPriorityGains
|
|
@@ -316,7 +357,7 @@ function evaluateStandardTrialForSeed({
|
|
|
316
357
|
fallbackTrial = trial;
|
|
317
358
|
}
|
|
318
359
|
if (alphaGain < 1) {
|
|
319
|
-
if (isWeakAlphaPrioritySeed(seed) &&
|
|
360
|
+
if (isWeakAlphaPrioritySeed(seed) && isCleanWeakAlphaPriorityCandidate(trial)) {
|
|
320
361
|
return trial;
|
|
321
362
|
}
|
|
322
363
|
continue;
|
|
@@ -370,8 +411,19 @@ export function evaluateRestorationCandidate({
|
|
|
370
411
|
});
|
|
371
412
|
const texturePenalty = textureAssessment.texturePenalty;
|
|
372
413
|
const gradientDrop = originalScores.gradientScore - processedScores.gradientScore;
|
|
414
|
+
const strongStandardSignalNearBlackOverride =
|
|
415
|
+
isStandardCandidateSource({ source }) &&
|
|
416
|
+
alphaGain === 1 &&
|
|
417
|
+
originalScores.spatialScore >= STANDARD_STRONG_SIGNAL_NEAR_BLACK_OVERRIDE_MIN_SPATIAL_SCORE &&
|
|
418
|
+
originalScores.gradientScore >= STANDARD_STRONG_SIGNAL_NEAR_BLACK_OVERRIDE_MIN_GRADIENT_SCORE &&
|
|
419
|
+
Math.abs(processedScores.spatialScore) <= STANDARD_STRONG_SIGNAL_NEAR_BLACK_OVERRIDE_MAX_RESIDUAL &&
|
|
420
|
+
processedScores.gradientScore <= STANDARD_STRONG_SIGNAL_NEAR_BLACK_OVERRIDE_MAX_GRADIENT &&
|
|
421
|
+
improvement >= STANDARD_STRONG_SIGNAL_NEAR_BLACK_OVERRIDE_MIN_IMPROVEMENT &&
|
|
422
|
+
gradientDrop >= STANDARD_STRONG_SIGNAL_NEAR_BLACK_OVERRIDE_MIN_GRADIENT_DROP &&
|
|
423
|
+
nearBlackIncrease <= STANDARD_STRONG_SIGNAL_NEAR_BLACK_OVERRIDE_MAX_NEAR_BLACK_INCREASE;
|
|
373
424
|
const nearBlackIncreaseAllowed =
|
|
374
425
|
nearBlackIncrease <= MAX_NEAR_BLACK_RATIO_INCREASE ||
|
|
426
|
+
strongStandardSignalNearBlackOverride ||
|
|
375
427
|
(
|
|
376
428
|
source === 'standard' &&
|
|
377
429
|
originalScores.spatialScore >= STANDARD_TEXT_OVERLAP_MIN_SPATIAL_SCORE &&
|
|
@@ -500,6 +552,12 @@ function ensureCandidateImageData(candidate, originalImageData) {
|
|
|
500
552
|
export function pickBetterCandidate(currentBest, candidate, minCostDelta = 0.005) {
|
|
501
553
|
if (!candidate?.accepted) return currentBest;
|
|
502
554
|
if (!currentBest) return candidate;
|
|
555
|
+
if (shouldPreserveCatalogOriginalSignal(currentBest, candidate)) {
|
|
556
|
+
return currentBest;
|
|
557
|
+
}
|
|
558
|
+
if (shouldPreferCatalogOriginalSignal(candidate, currentBest)) {
|
|
559
|
+
return candidate;
|
|
560
|
+
}
|
|
503
561
|
if (shouldPreserveStrongStandardAnchor(currentBest, candidate)) {
|
|
504
562
|
return currentBest;
|
|
505
563
|
}
|
|
@@ -554,6 +612,75 @@ function hasStrongCanonicalAnchorSignal(candidate) {
|
|
|
554
612
|
baseSpatial >= STANDARD_LOCAL_SHIFT_STRONG_BASE_SPATIAL_SCORE;
|
|
555
613
|
}
|
|
556
614
|
|
|
615
|
+
function hasReliableCandidateOriginalSignal(candidate) {
|
|
616
|
+
return hasReliableStandardWatermarkSignal({
|
|
617
|
+
spatialScore: candidate?.originalSpatialScore,
|
|
618
|
+
gradientScore: candidate?.originalGradientScore
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
function hasMuchStrongerOriginalSignal(candidate, otherCandidate) {
|
|
623
|
+
const spatial = Number(candidate?.originalSpatialScore);
|
|
624
|
+
const gradient = Number(candidate?.originalGradientScore);
|
|
625
|
+
const otherSpatial = Number(otherCandidate?.originalSpatialScore);
|
|
626
|
+
const otherGradient = Number(otherCandidate?.originalGradientScore);
|
|
627
|
+
if (
|
|
628
|
+
!Number.isFinite(spatial) ||
|
|
629
|
+
!Number.isFinite(gradient) ||
|
|
630
|
+
!Number.isFinite(otherSpatial) ||
|
|
631
|
+
!Number.isFinite(otherGradient)
|
|
632
|
+
) {
|
|
633
|
+
return false;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
return spatial >= otherSpatial + STRONG_ORIGINAL_SIGNAL_SPATIAL_ADVANTAGE &&
|
|
637
|
+
gradient >= otherGradient + STRONG_ORIGINAL_SIGNAL_GRADIENT_ADVANTAGE;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
function isCatalogVariantCandidate(candidate) {
|
|
641
|
+
return candidate?.provenance?.catalogVariant === true;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
function isCurrentLargeMarginCatalogCandidate(candidate) {
|
|
645
|
+
return isCatalogVariantCandidate(candidate) &&
|
|
646
|
+
candidate?.config?.logoSize === 48 &&
|
|
647
|
+
candidate.config.marginRight === 96 &&
|
|
648
|
+
candidate.config.marginBottom === 96;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
function isPreviewAnchorCandidate(candidate) {
|
|
652
|
+
return candidate?.provenance?.previewAnchor === true;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
function shouldPreferCatalogOriginalSignal(candidate, currentBest) {
|
|
656
|
+
if (!isCurrentLargeMarginCatalogCandidate(candidate)) return false;
|
|
657
|
+
if (currentBest?.provenance?.localShift === true || currentBest?.provenance?.sizeJitter === true) {
|
|
658
|
+
return false;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
const candidateReliable = hasReliableCandidateOriginalSignal(candidate);
|
|
662
|
+
const currentReliable = hasReliableCandidateOriginalSignal(currentBest);
|
|
663
|
+
if (candidateReliable && !currentReliable) return true;
|
|
664
|
+
|
|
665
|
+
return candidateReliable &&
|
|
666
|
+
currentReliable &&
|
|
667
|
+
isPreviewAnchorCandidate(currentBest) &&
|
|
668
|
+
hasMuchStrongerOriginalSignal(candidate, currentBest);
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
function shouldPreserveCatalogOriginalSignal(currentBest, candidate) {
|
|
672
|
+
if (!isCurrentLargeMarginCatalogCandidate(currentBest)) return false;
|
|
673
|
+
if (!isPreviewAnchorCandidate(candidate)) return false;
|
|
674
|
+
|
|
675
|
+
const currentReliable = hasReliableCandidateOriginalSignal(currentBest);
|
|
676
|
+
const candidateReliable = hasReliableCandidateOriginalSignal(candidate);
|
|
677
|
+
if (currentReliable && !candidateReliable) return true;
|
|
678
|
+
|
|
679
|
+
return currentReliable &&
|
|
680
|
+
candidateReliable &&
|
|
681
|
+
hasMuchStrongerOriginalSignal(currentBest, candidate);
|
|
682
|
+
}
|
|
683
|
+
|
|
557
684
|
function hasWeakDriftEvidence(candidate) {
|
|
558
685
|
const candidateSpatial = Number(candidate?.originalSpatialScore);
|
|
559
686
|
const candidateGradient = Number(candidate?.originalGradientScore);
|
|
@@ -1158,7 +1285,8 @@ function resolveStandardAnchorSelection({
|
|
|
1158
1285
|
alpha96Variants,
|
|
1159
1286
|
getAlphaMap,
|
|
1160
1287
|
resolveAlphaMap,
|
|
1161
|
-
alphaPriorityGains
|
|
1288
|
+
alphaPriorityGains,
|
|
1289
|
+
forceCatalogVariants = false
|
|
1162
1290
|
}) {
|
|
1163
1291
|
let standardCandidateSeeds = buildStandardCandidateSeeds({
|
|
1164
1292
|
originalImageData,
|
|
@@ -1178,8 +1306,16 @@ function resolveStandardAnchorSelection({
|
|
|
1178
1306
|
});
|
|
1179
1307
|
|
|
1180
1308
|
const shouldExpandStandardCatalog =
|
|
1309
|
+
forceCatalogVariants ||
|
|
1181
1310
|
!standardSelection.hasReliableStandardMatch &&
|
|
1182
|
-
(
|
|
1311
|
+
(
|
|
1312
|
+
!standardSelection.standardTrial ||
|
|
1313
|
+
shouldEscalateSearch(standardSelection.standardTrial) ||
|
|
1314
|
+
(
|
|
1315
|
+
matchOfficialGeminiImageSize(originalImageData.width, originalImageData.height) === null &&
|
|
1316
|
+
shouldExpandCatalogForWeakOriginalStandardEvidence(standardSelection.standardTrial)
|
|
1317
|
+
)
|
|
1318
|
+
);
|
|
1183
1319
|
|
|
1184
1320
|
if (shouldExpandStandardCatalog) {
|
|
1185
1321
|
standardCandidateSeeds = buildStandardCandidateSeeds({
|
|
@@ -1252,6 +1388,16 @@ function promoteBaseCandidate(baseCandidate, baseDecisionTier, candidate, {
|
|
|
1252
1388
|
};
|
|
1253
1389
|
}
|
|
1254
1390
|
|
|
1391
|
+
if (
|
|
1392
|
+
reliableMatch &&
|
|
1393
|
+
shouldPreferCatalogOriginalSignal(promotion.candidate, baseCandidate)
|
|
1394
|
+
) {
|
|
1395
|
+
return {
|
|
1396
|
+
baseCandidate: promotion.candidate,
|
|
1397
|
+
baseDecisionTier: promotion.decisionTier
|
|
1398
|
+
};
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1255
1401
|
const previousCandidate = baseCandidate;
|
|
1256
1402
|
const nextCandidate = pickBetterCandidate(baseCandidate, promotion.candidate, minCostDelta);
|
|
1257
1403
|
return {
|
|
@@ -1334,7 +1480,8 @@ function refineSelectedAnchorCandidate({
|
|
|
1334
1480
|
baseCandidate,
|
|
1335
1481
|
baseDecisionTier,
|
|
1336
1482
|
adaptiveConfidence,
|
|
1337
|
-
alphaGainCandidates
|
|
1483
|
+
alphaGainCandidates,
|
|
1484
|
+
allowTemplateWarp = true
|
|
1338
1485
|
}) {
|
|
1339
1486
|
let selectedTrial = ensureCandidateImageData(baseCandidate, originalImageData);
|
|
1340
1487
|
let alphaMap = baseCandidate.alphaMap;
|
|
@@ -1345,19 +1492,21 @@ function refineSelectedAnchorCandidate({
|
|
|
1345
1492
|
let templateWarp = null;
|
|
1346
1493
|
let selectedAlphaGain = baseCandidate.alphaGain ?? 1;
|
|
1347
1494
|
|
|
1348
|
-
const warpCandidate =
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1495
|
+
const warpCandidate = allowTemplateWarp
|
|
1496
|
+
? findBestTemplateWarp({
|
|
1497
|
+
originalImageData,
|
|
1498
|
+
alphaMap,
|
|
1499
|
+
position,
|
|
1500
|
+
baselineSpatialScore: selectedTrial.originalSpatialScore,
|
|
1501
|
+
baselineGradientScore: selectedTrial.originalGradientScore,
|
|
1502
|
+
shiftCandidates: selectedTrial.provenance?.previewAnchor === true
|
|
1503
|
+
? PREVIEW_TEMPLATE_ALIGN_SHIFTS
|
|
1504
|
+
: TEMPLATE_ALIGN_SHIFTS,
|
|
1505
|
+
scaleCandidates: selectedTrial.provenance?.previewAnchor === true
|
|
1506
|
+
? PREVIEW_TEMPLATE_ALIGN_SCALES
|
|
1507
|
+
: TEMPLATE_ALIGN_SCALES
|
|
1508
|
+
})
|
|
1509
|
+
: null;
|
|
1361
1510
|
if (warpCandidate) {
|
|
1362
1511
|
const warpedTrial = evaluateRestorationCandidate({
|
|
1363
1512
|
originalImageData,
|
|
@@ -1433,6 +1582,7 @@ export function selectInitialCandidate({
|
|
|
1433
1582
|
alpha96,
|
|
1434
1583
|
getAlphaMap,
|
|
1435
1584
|
allowAdaptiveSearch,
|
|
1585
|
+
allowAutomaticSearch = true,
|
|
1436
1586
|
alphaGainCandidates,
|
|
1437
1587
|
alphaPriorityGains = [1],
|
|
1438
1588
|
alpha96Variants = null
|
|
@@ -1455,7 +1605,8 @@ export function selectInitialCandidate({
|
|
|
1455
1605
|
alpha96Variants,
|
|
1456
1606
|
getAlphaMap,
|
|
1457
1607
|
resolveAlphaMap,
|
|
1458
|
-
alphaPriorityGains
|
|
1608
|
+
alphaPriorityGains,
|
|
1609
|
+
forceCatalogVariants: !allowAutomaticSearch
|
|
1459
1610
|
});
|
|
1460
1611
|
let baseCandidate = null;
|
|
1461
1612
|
let baseDecisionTier = 'insufficient';
|
|
@@ -1498,23 +1649,26 @@ export function selectInitialCandidate({
|
|
|
1498
1649
|
alphaGainCandidates
|
|
1499
1650
|
}));
|
|
1500
1651
|
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
({
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1652
|
+
if (allowAutomaticSearch) {
|
|
1653
|
+
const previewAnchorCandidate = searchBottomRightPreviewCandidate({
|
|
1654
|
+
originalImageData,
|
|
1655
|
+
config,
|
|
1656
|
+
alpha48,
|
|
1657
|
+
alpha96,
|
|
1658
|
+
getAlphaMap,
|
|
1659
|
+
resolveAlphaMap,
|
|
1660
|
+
adaptiveConfidence
|
|
1661
|
+
});
|
|
1662
|
+
if (previewAnchorCandidate) {
|
|
1663
|
+
({
|
|
1664
|
+
baseCandidate,
|
|
1665
|
+
baseDecisionTier
|
|
1666
|
+
} = promoteBaseCandidate(baseCandidate, baseDecisionTier, previewAnchorCandidate));
|
|
1667
|
+
}
|
|
1515
1668
|
}
|
|
1516
1669
|
|
|
1517
1670
|
if (
|
|
1671
|
+
allowAutomaticSearch &&
|
|
1518
1672
|
baseDecisionTier !== 'direct-match' &&
|
|
1519
1673
|
!baseCandidate?.provenance?.previewAnchor &&
|
|
1520
1674
|
shouldEscalateSearch(baseCandidate)
|
|
@@ -1536,6 +1690,7 @@ export function selectInitialCandidate({
|
|
|
1536
1690
|
}
|
|
1537
1691
|
|
|
1538
1692
|
if (
|
|
1693
|
+
allowAutomaticSearch &&
|
|
1539
1694
|
baseDecisionTier !== 'direct-match' &&
|
|
1540
1695
|
baseCandidate?.provenance?.sizeJitter === true &&
|
|
1541
1696
|
!baseCandidate?.provenance?.previewAnchor &&
|
|
@@ -1571,7 +1726,7 @@ export function selectInitialCandidate({
|
|
|
1571
1726
|
});
|
|
1572
1727
|
};
|
|
1573
1728
|
|
|
1574
|
-
if (shouldEvaluateAdaptive()) {
|
|
1729
|
+
if (allowAutomaticSearch && shouldEvaluateAdaptive()) {
|
|
1575
1730
|
({
|
|
1576
1731
|
adaptive,
|
|
1577
1732
|
adaptiveConfidence,
|
|
@@ -1593,8 +1748,9 @@ export function selectInitialCandidate({
|
|
|
1593
1748
|
reliableMatch: hasReliableAdaptiveWatermarkSignal(adaptive)
|
|
1594
1749
|
}));
|
|
1595
1750
|
}
|
|
1596
|
-
|
|
1751
|
+
|
|
1597
1752
|
if (
|
|
1753
|
+
allowAutomaticSearch &&
|
|
1598
1754
|
!baseCandidate?.provenance?.previewAnchor &&
|
|
1599
1755
|
!hasReliableAdaptiveWatermarkSignal(adaptive) &&
|
|
1600
1756
|
shouldSearchNearbyStandardCandidate(baseCandidate, originalImageData)
|
|
@@ -1613,7 +1769,7 @@ export function selectInitialCandidate({
|
|
|
1613
1769
|
}
|
|
1614
1770
|
|
|
1615
1771
|
if (!baseCandidate) {
|
|
1616
|
-
if (hasReliableStandardMatch && standardTrial) {
|
|
1772
|
+
if (hasReliableStandardMatch && standardTrial?.accepted) {
|
|
1617
1773
|
baseCandidate = standardTrial;
|
|
1618
1774
|
baseDecisionTier = 'direct-match';
|
|
1619
1775
|
} else if (hasReliableAdaptiveWatermarkSignal(adaptive) && adaptiveTrial) {
|
|
@@ -1651,6 +1807,37 @@ export function selectInitialCandidate({
|
|
|
1651
1807
|
baseDecisionTier = hasReliableStandardMatch ? 'direct-match' : 'validated-match';
|
|
1652
1808
|
}
|
|
1653
1809
|
|
|
1810
|
+
if (!allowAutomaticSearch && !isStrictFixedCoreCandidate(baseCandidate)) {
|
|
1811
|
+
baseCandidate = null;
|
|
1812
|
+
baseDecisionTier = 'insufficient';
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1815
|
+
if (!baseCandidate) {
|
|
1816
|
+
const validatedCandidate = allowAutomaticSearch
|
|
1817
|
+
? pickBestValidatedCandidate([standardTrial, adaptiveTrial])
|
|
1818
|
+
: null;
|
|
1819
|
+
if (!validatedCandidate) {
|
|
1820
|
+
return {
|
|
1821
|
+
selectedTrial: null,
|
|
1822
|
+
source: 'skipped',
|
|
1823
|
+
alphaMap: fallbackAlphaMap,
|
|
1824
|
+
position,
|
|
1825
|
+
config,
|
|
1826
|
+
adaptiveConfidence,
|
|
1827
|
+
standardSpatialScore,
|
|
1828
|
+
standardGradientScore,
|
|
1829
|
+
templateWarp: null,
|
|
1830
|
+
alphaGain: 1,
|
|
1831
|
+
decisionTier: 'insufficient'
|
|
1832
|
+
};
|
|
1833
|
+
}
|
|
1834
|
+
baseCandidate = {
|
|
1835
|
+
...validatedCandidate,
|
|
1836
|
+
source: `${validatedCandidate.source}+validated`
|
|
1837
|
+
};
|
|
1838
|
+
baseDecisionTier = 'validated-match';
|
|
1839
|
+
}
|
|
1840
|
+
|
|
1654
1841
|
const {
|
|
1655
1842
|
selectedTrial,
|
|
1656
1843
|
source,
|
|
@@ -1665,7 +1852,8 @@ export function selectInitialCandidate({
|
|
|
1665
1852
|
baseCandidate,
|
|
1666
1853
|
baseDecisionTier,
|
|
1667
1854
|
adaptiveConfidence,
|
|
1668
|
-
alphaGainCandidates
|
|
1855
|
+
alphaGainCandidates,
|
|
1856
|
+
allowTemplateWarp: allowAutomaticSearch
|
|
1669
1857
|
});
|
|
1670
1858
|
|
|
1671
1859
|
return {
|
|
@@ -25,6 +25,11 @@ const GEMINI_3X_CURRENT_1K_LARGE_MARGIN_WATERMARK_CONFIG = Object.freeze({
|
|
|
25
25
|
marginRight: 96,
|
|
26
26
|
marginBottom: 96
|
|
27
27
|
});
|
|
28
|
+
const KNOWN_FIXED_GEMINI_WATERMARK_CONFIGS_BY_SIZE = Object.freeze({
|
|
29
|
+
'1408x768': Object.freeze([
|
|
30
|
+
Object.freeze({ logoSize: 46, marginRight: 32, marginBottom: 32, fixedVariant: true })
|
|
31
|
+
])
|
|
32
|
+
});
|
|
28
33
|
|
|
29
34
|
// Gemini image generation does not emit arbitrary dimensions.
|
|
30
35
|
// The models use a discrete set of official sizes, so the catalog is a better
|
|
@@ -204,6 +209,15 @@ function isOfficialOrKnownGeminiDimensions(width, height) {
|
|
|
204
209
|
return matchOfficialGeminiImageSize(width, height) !== null;
|
|
205
210
|
}
|
|
206
211
|
|
|
212
|
+
function resolveKnownFixedGeminiWatermarkConfigs(width, height) {
|
|
213
|
+
const normalizedWidth = normalizeDimension(width);
|
|
214
|
+
const normalizedHeight = normalizeDimension(height);
|
|
215
|
+
if (!normalizedWidth || !normalizedHeight) return [];
|
|
216
|
+
|
|
217
|
+
const configs = KNOWN_FIXED_GEMINI_WATERMARK_CONFIGS_BY_SIZE[`${normalizedWidth}x${normalizedHeight}`];
|
|
218
|
+
return Array.isArray(configs) ? configs.map((config) => ({ ...config })) : [];
|
|
219
|
+
}
|
|
220
|
+
|
|
207
221
|
export function resolveOfficialGeminiSearchConfigs(
|
|
208
222
|
width,
|
|
209
223
|
height,
|
|
@@ -311,6 +325,7 @@ export function resolveGeminiWatermarkSearchConfigs(width, height, defaultConfig
|
|
|
311
325
|
if (defaultConfig) {
|
|
312
326
|
configs.push(defaultConfig);
|
|
313
327
|
}
|
|
328
|
+
configs.push(...resolveKnownFixedGeminiWatermarkConfigs(width, height));
|
|
314
329
|
configs.push(...resolveOfficialGeminiSearchConfigs(width, height));
|
|
315
330
|
const currentLargeMarginVariant = createCurrentLargeMarginVariantConfig(defaultConfig, width, height);
|
|
316
331
|
if (currentLargeMarginVariant) {
|