How to create a flutter camera with mask and framing (automatic)?

23 Views Asked by At

Please help me create a flutter camera app with a mask layout. I do not know how to make the camera have a rectangular mask that automatically frames the image after shooting.

At the moment, I'm making an image and then manually cropping it, after which it is saved in the gallery.

The code looks like this

Main.dart

import 'dart:io';

import 'package:app_math_img/services/image_picker_service.dart';
import 'package:flutter/material.dart';
import 'package:image_cropper/image_cropper.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:image_picker/image_picker.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({super.key, required this.title});

  final String title;
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

  @override
  State<MyHomePage> createState() => _MyHomePageState(_scaffoldKey);
}

class _MyHomePageState extends State<MyHomePage> {
  final GlobalKey<ScaffoldState> _scaffoldKey;

  _MyHomePageState(this._scaffoldKey);
  XFile? imageFile;
  Future<void> saveImageToGallery() async {
    // Save image to gallery
    await ImageGallerySaver.saveFile(imageFile!.path);

    // Show a message to the user
    if (_scaffoldKey.currentContext != null) {
      ScaffoldMessenger.of(_scaffoldKey.currentContext!).showSnackBar(
        const SnackBar(
          content: Text('Image saved to Gallery'),
        ),
      );
    }

    // Trigger a rebuild to display the saved image
    setState(() {});
  }

  void _onClick() async {
    imageFile = await ImagePickerService().pickCropImage(
      cropAspectRatio: const CropAspectRatio(ratioX: 16, ratioY: 9),
      imageSource: ImageSource.camera,
    );
    if (imageFile != null) {
      saveImageToGallery();
    }
    setState(() => {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: widget._scaffoldKey,
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: imageFile != null
            ? Image(image: FileImage(File(imageFile!.path)))
            : const Text('No image selected'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _onClick,
        child: const Icon(Icons.camera),
      ),
    );
  }
}

image_picker_service.dart

import 'package:image_cropper/image_cropper.dart';
import 'package:image_picker/image_picker.dart';

class ImagePickerService {
  Future<XFile?> pickCropImage({
    required CropAspectRatio cropAspectRatio,
    required ImageSource imageSource,
  }) async {
    //Pick image
    XFile? pickImage = await ImagePicker().pickImage(source: imageSource);
    if (pickImage == null) return null;

    //Crop picked image
    CroppedFile? croppedFile = await ImageCropper().cropImage(
      sourcePath: pickImage.path,
      aspectRatio: cropAspectRatio,
      compressQuality: 90,
      compressFormat: ImageCompressFormat.jpg,
    );
    if (croppedFile == null) return null;

    return XFile(croppedFile.path);
  }
}
0

There are 0 best solutions below