flutter自定义头像拍照

703 阅读1分钟

项目里有个拍照的需求,大概是这样子的

IMG_4516.PNG 实现这个很简单,就是底部是照相机,上面再弄个遮罩把相机给遮起来

我们先实现相机的展示

Widget build(BuildContext context) {
  final size = MediaQuery.of(context).size;
  final width = size.width;
  final top = width*2/3 - width/2;
  final bottom = width*4/3 - width/2;
  return Material(
    color: Colors.white,
    child:  Stack(
      children: [
        Column(
          children: [
            SafeArea(child: Align(
              alignment: Alignment(0.9, 0),
              child: IconButton(
                icon: Icon(Icons.clear_outlined, color: Colors.blue,),
                onPressed: ()=> Navigator.pop(context),
              ),
            ), top: true,),
            Container(
              // color: Colors.red,
              height: width,
              width: size.width,
              child: Stack(
                children: [
                  Container(
                    padding: EdgeInsets.symmetric(horizontal: 0.125*width),
                    height: width,
                    child: initialState ?
                    CameraPreview(controller) : const SizedBox.expand(),
                  ),


                ],
              ),
            ),
            Center(
              child: Text('请保持头像在圆圈内', textAlign: TextAlign.center,style: TextStyle(color: Colors.grey, fontSize: 18, fontWeight: FontWeight.w500)),
            ),
            SafeArea(child: SizedBox(), bottom: false,)
          ],
        ),
      ],
    ),
  );
}

运行代码

IMG_4515.PNG

Stack(
  children: [
    Container(
      padding: EdgeInsets.symmetric(horizontal: 0.125*width),
      height: width,
      child: initialState ?
      CameraPreview(controller) : const SizedBox.expand(),
    ),
    Container(
      padding: EdgeInsets.symmetric(horizontal: 0.125*width),
      height: width,
      child: CustomPaint(
        size: Size(width*0.75, width),
        painter: CiclePainter(),
      ),
    ),

  ],
)

我们需要在相机上添加一个圆形的镂空的widget

void paint(Canvas canvas, Size size) {
  final height = size.height;
  final width = size.width;

  // 创建画笔
  canvas.translate(0, 0);
  final Paint paint = Paint();
  paint.color = Colors.white;
  Path path = Path();
  path
    ..moveTo(0, 0)
    ..lineTo(width, 0)
    ..lineTo(width, height)
    ..lineTo(0,height)
    ..close();
  var pathOval =Path()..addOval(Rect.fromCenter(center: Offset(width/2, height/2),width: width,height: width));
  canvas.drawPath(Path.combine(PathOperation.difference, path, pathOval), paint);
}

大概步骤就是先画一个和相机一样大小的矩形,在镂空一个矩形内的圆。 Path.combine(PathOperation.difference, path, pathOval) 我理解是这个方法可以将两个路径相交的地方抵消掉,最后就变成这样

IMG_4516.PNG 项目链接 [github.com/dongzhengga…]