需要用到的第三方库:
permission_handler: ^8.1.3 //权限请求
image_picker: ^0.8.0 //图片选择
crop_your_image: ^0.6.0+1 //图片裁剪
代码:
//打开相册选择图片
chooserPic() async {
final ImagePicker _picker = ImagePicker();
final XFile? image = await _picker.pickImage(source: ImageSource.gallery);
print("ChooserImage:${image!.path}");
Uint8List imageByte = await image.readAsBytes();
PageUtil().open(context, CropImage(imageByte));
}
PageUtil().open()是我自己写的路由跳转方法,读者可以自行替换成下面的常规写法
void open(BuildContext context, Widget page) {
Navigator.push(context, MaterialPageRoute(builder: (context) => page));
}
CropImage页面:
class CropImage extends StatefulWidget {
Uint8List imageByte;
CropImage(this.imageByte);
@override
State createState() {
return CropImageState();
}
}
class CropImageState extends State {
final _controller = CropController();
CropImage() { //确认裁剪时调用这个方法
_controller.crop();
}
//将回调拿到的Uint8List格式的图片转换为File格式
SaveImage(Uint8List imageByte) async {
EasyLoading.show();
final tempDir = await getTemporaryDirectory();
final file = await new File('${tempDir.path}/image.jpg').create();
file.writeAsBytesSync(imageByte);
print("${file.path}");
EasyLoading.dismiss();
}
@override
Widget build(BuildContext context) {
return MyPage( //MyPage是笔者自己写的组件,读者可以忽略,不是主要代码
"頭貼裁切",
Column(
children: [
Container(height: 24),
Expanded( //Crop是裁剪控件
child: Crop(
image: widget.imageByte,
controller: _controller,
onCropped: (image) { //裁剪完成的回调
SaveImage(image);
},
aspectRatio: 1,
initialSize: 0.8,
withCircleUi: true,
baseColor: Colors.black,
maskColor: Colors.black.withAlpha(150),
cornerDotBuilder: (size, edgeAlignment) => const DotControl(color: Colors.white54),
)),
Container(
padding: EdgeInsets.fromLTRB(35, 16, 35, 16),
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Text("符合頭貼尺寸的裁切範圍", style: TextStyle(fontSize: 12, color: MyColor.White)),
Button("儲存", radius: 13,
height: 26,
width: 71,
bgColor: MyColor.Red,
fontSize: 12,
onTap: CropImage) //点击开始裁剪
]))
],
),
bgColor: MyColor.Black,
isBlackTxt: false);
}
}
主要代码:裁剪区域
Crop(
image: widget.imageByte,
controller: _controller,
onCropped: (image) {//裁剪完成的回调
SaveImage(image);
},
aspectRatio: 1,
initialSize: 0.8,
withCircleUi: true,
baseColor: Colors.black,
maskColor: Colors.black.withAlpha(150),
cornerDotBuilder: (size, edgeAlignment) => const DotControl(color: Colors.white54),
)