58 lines
1.7 KiB
Dart
58 lines
1.7 KiB
Dart
|
|
import 'dart:math' as math;
|
||
|
|
import 'dart:ui';
|
||
|
|
|
||
|
|
/// Shared capture guide geometry (same as the on-screen shooting frame).
|
||
|
|
class GuideFrame {
|
||
|
|
static const double aspect = 63 / 88;
|
||
|
|
static const double maxHeightFraction = 0.62;
|
||
|
|
static const double maxWidthFraction = 0.78;
|
||
|
|
static const double centerYFraction = 0.46;
|
||
|
|
|
||
|
|
/// Guide rect inside a viewport (preview overlay coordinates).
|
||
|
|
static Rect inViewport(Size size) {
|
||
|
|
final maxH = size.height * maxHeightFraction;
|
||
|
|
final maxW = size.width * maxWidthFraction;
|
||
|
|
var h = maxH;
|
||
|
|
var w = h * aspect;
|
||
|
|
if (w > maxW) {
|
||
|
|
w = maxW;
|
||
|
|
h = w / aspect;
|
||
|
|
}
|
||
|
|
return Rect.fromCenter(
|
||
|
|
center: Offset(size.width / 2, size.height * centerYFraction),
|
||
|
|
width: w,
|
||
|
|
height: h,
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Map the viewport guide into image pixels when the image is shown with
|
||
|
|
/// [BoxFit.cover] in [viewport] (camera preview).
|
||
|
|
static Rect inCoverImage({
|
||
|
|
required Size viewport,
|
||
|
|
required Size imageSize,
|
||
|
|
}) {
|
||
|
|
final guide = inViewport(viewport);
|
||
|
|
final scale = math.max(
|
||
|
|
viewport.width / imageSize.width,
|
||
|
|
viewport.height / imageSize.height,
|
||
|
|
);
|
||
|
|
final dispW = imageSize.width * scale;
|
||
|
|
final dispH = imageSize.height * scale;
|
||
|
|
final ox = (viewport.width - dispW) / 2;
|
||
|
|
final oy = (viewport.height - dispH) / 2;
|
||
|
|
|
||
|
|
final mapped = Rect.fromLTRB(
|
||
|
|
(guide.left - ox) / scale,
|
||
|
|
(guide.top - oy) / scale,
|
||
|
|
(guide.right - ox) / scale,
|
||
|
|
(guide.bottom - oy) / scale,
|
||
|
|
);
|
||
|
|
return mapped.intersect(
|
||
|
|
Rect.fromLTWH(0, 0, imageSize.width, imageSize.height),
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Guide applied directly in image space (gallery / no viewport).
|
||
|
|
static Rect inImage(Size imageSize) => inViewport(imageSize);
|
||
|
|
}
|