fix: centrage de la cible image pleine ecran respectant la prise origine au niveau des coins verts/orange
This commit is contained in:
@@ -884,16 +884,23 @@ class _CaptureScreenState extends State<CaptureScreen>
|
||||
}
|
||||
}
|
||||
|
||||
/// Réduit fortement la résolution de la photo pour accélérer tous les
|
||||
/// écrans suivants (crop, calibration, plotting). 1080 px de côté max
|
||||
/// + JPEG qualité 70 : largement suffisant pour la détection visuelle.
|
||||
/// Recadre la photo sur la zone du viseur PUIS réduit sa résolution, en un
|
||||
/// seul décodage dans un Isolate (thread UI fluide).
|
||||
///
|
||||
/// Baisser `maxSide` (ex. 900) ou `quality` (ex. 60) rend le chargement
|
||||
/// encore plus rapide au prix d'un peu de finesse à l'écran.
|
||||
/// 1) Recadrage viseur : carré centré à 85 % du petit côté de la photo. C'est
|
||||
/// EXACTEMENT le cadre des 4 coins verts/orange affiché à la capture
|
||||
/// (`SizedBox` de `0.85 * largeur écran`, centré, l'aperçu caméra remplissant
|
||||
/// la largeur). → l'écran de centrage ne reçoit QUE ce qui était visé entre
|
||||
/// les coins, sans le fond capturé autour : plus d'impression de « dézoom ».
|
||||
/// 2) Dégradation résolution : 1080 px de côté max + JPEG qualité 70, largement
|
||||
/// suffisant pour la détection visuelle et bien plus rapide à recharger.
|
||||
///
|
||||
/// Baisser `maxSide` (ex. 900) ou `quality` (ex. 60) accélère encore au prix
|
||||
/// d'un peu de finesse à l'écran.
|
||||
Future<String> _downscaleForPipeline(String sourcePath) async {
|
||||
// On résout le chemin de sortie sur le thread UI (path_provider a besoin
|
||||
// du canal de plateforme), puis tout le travail lourd (décodage, resize,
|
||||
// réencodage JPEG) part dans un Isolate → aucun gel du thread UI.
|
||||
// du canal de plateforme), puis tout le travail lourd (décodage, crop,
|
||||
// resize, réencodage JPEG) part dans un Isolate → aucun gel du thread UI.
|
||||
final tempDir = await getTemporaryDirectory();
|
||||
final outPath =
|
||||
'${tempDir.path}/downscaled_${DateTime.now().millisecondsSinceEpoch}.jpg';
|
||||
@@ -903,21 +910,34 @@ class _CaptureScreenState extends State<CaptureScreen>
|
||||
final decoded = img.decodeImage(bytes);
|
||||
if (decoded == null) return sourcePath;
|
||||
|
||||
const int maxSide = 1080;
|
||||
final int longest = math.max(decoded.width, decoded.height);
|
||||
if (longest <= maxSide) {
|
||||
return sourcePath; // déjà assez petite, rien à faire
|
||||
}
|
||||
|
||||
final double ratio = maxSide / longest;
|
||||
final resized = img.copyResize(
|
||||
// 1) Recadrage sur la zone du viseur (carré centré à 85 % du petit côté).
|
||||
final int side = (math.min(decoded.width, decoded.height) * 0.85).round();
|
||||
final int cropX =
|
||||
((decoded.width - side) / 2).round().clamp(0, decoded.width - 1);
|
||||
final int cropY =
|
||||
((decoded.height - side) / 2).round().clamp(0, decoded.height - 1);
|
||||
img.Image result = img.copyCrop(
|
||||
decoded,
|
||||
width: (decoded.width * ratio).round(),
|
||||
height: (decoded.height * ratio).round(),
|
||||
interpolation: img.Interpolation.linear, // rapide
|
||||
x: cropX,
|
||||
y: cropY,
|
||||
width: math.min(side, decoded.width - cropX),
|
||||
height: math.min(side, decoded.height - cropY),
|
||||
);
|
||||
|
||||
File(outPath).writeAsBytesSync(img.encodeJpg(resized, quality: 70));
|
||||
// 2) Dégradation résolution si nécessaire.
|
||||
const int maxSide = 1080;
|
||||
final int longest = math.max(result.width, result.height);
|
||||
if (longest > maxSide) {
|
||||
final double ratio = maxSide / longest;
|
||||
result = img.copyResize(
|
||||
result,
|
||||
width: (result.width * ratio).round(),
|
||||
height: (result.height * ratio).round(),
|
||||
interpolation: img.Interpolation.linear, // rapide
|
||||
);
|
||||
}
|
||||
|
||||
File(outPath).writeAsBytesSync(img.encodeJpg(result, quality: 70));
|
||||
return outPath;
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user