ClipPath allows you to define a custom shape provided by a CustomerClipper. We show Image widget in a ClipPath which has bottom wave.
import 'dart:ui'; import 'package:flutter/material.dart'; class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { @override void initState() { super.initState(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.orangeAccent, appBar: AppBar( title: Text('Wave Image'), backgroundColor: Colors.orange, ), body: SafeArea( child: ClipPath( child: Image.network('https://cdn.pixabay.com/photo/2021/02/06/19/29/pancakes-5989136_960_720.jpg'), clipper: BottomWaveClipper(), ), )); } } class BottomWaveClipper extends CustomClipper<Path> { @override Path getClip(Size size) { var waveHeight = 10; Path path = new Path(); final lowPoint = size.height - waveHeight; final highPoint = size.height - waveHeight*2; path.lineTo(0, size.height); path.quadraticBezierTo( size.width / 4, highPoint, size.width / 2, lowPoint); path.quadraticBezierTo( 3 / 4 * size.width, size.height, size.width, lowPoint); path.lineTo(size.width, 0); return path; } @override bool shouldReclip(CustomClipper<Path> oldClipper) => false; }