前置数据:
String labelObject = {
"leftTop": {
"x": 30,
"y": 50,
},
"rightBottom": {
"x": 200,
"y": 200,
}
}
String imageObject = {
"imagePath": "someUrl.jpg",
"width": 1024,
"height": 768,
}
目标:
图片大小为1024*768, 希望仅能显示labelObject范围内的图片内容。
解决方案
1. 使用Stack布局,最简单
double labelWidth = labelObject.rightBottom.x - labelObject.leftTop.x;
double labelHeight = labelObject.rightBottom.y - labelObject.leftTop.y;
SizedBox(
height: 150,
width: double.infinity,
child: FittedBox(
fit: BoxFit.contain,
child: SizedBox(
width: labelWidth,
height: labelHeight,
child: Stack(
children: [
Positioned(
top: -labelObject.leftTop.y,
left: -labelObject.leftTop.x,
child: Image.file(
File(imageObject.imagePath),
),
),
],
),
),
),
),
2. 使用Align, alignment参数比较难理解
double labelWidth = labelObject.rightBottom.x - labelObject.leftTop.x;
double labelHeight = labelObject.rightBottom.y - labelObject.leftTop.y;
double labelCenterX = (labelObject.rightBottom.x + labelObject.leftTop.x) / 2;
double labelCenterY = (labelObject.rightBottom.y + labelObject.leftTop.y) / 2;
double offsetX = labelCenterX - imageObject.width / 2;
double offsetY = labelCenterY - imageObject.height / 2;
double offsetRangeX = (imageObject.width - labelWidth) / 2;
double offsetRangeY = (imageObject.height - labelHeight) / 2;
double xAlign = offsetRangeX == 0 ? 0 : offsetX / offsetRangeX;
double yAlign = offsetRangeY == 0 ? 0 : offsetY / offsetRangeY;
SizedBox(
height: 300,
width: double.infinity,
child: FittedBox(
fit: BoxFit.contain,
child: Container(
color: Colors.red,
child: ClipRect(
child: Align(
widthFactor: labelWidth / imageObject.width,
heightFactor: labelHeight / imageObject.height,
alignment: Alignment(xAlign, yAlign),
child: Image.file(File(imageObject.imagePath)),
),
),
),
),
),
3. 同样使用Align,但使用transform可以避免Aligin参数很不好计算的问题
double labelCenterX = (labelObject.rightBottom.x + labelObject.leftTop.x) / 2;
double labelCenterY = (labelObject.rightBottom.y + labelObject.leftTop.y) / 2;
SizedBox(
height: 150,
width: double.infinity,
child: FittedBox(
fit: BoxFit.contain,
child: Container(
color: Colors.red,
child: ClipRect(
child: Align(
widthFactor: labelWidth / imageObject.width,
heightFactor: labelHeight / imageObject.height,
alignment: Alignment.center,
child: Transform.translate(
offset: Offset(
-labelCenterX + imageObject.width / 2,
-labelCenterY + imageObject.height / 2,
),
child: Image.file(File(imageObject.imagePath)),
),
),
),
),
),
),