Skip to content

A Flutter camera package that provides a customizable grid overlay for precise photo composition. Features include adjustable grid rows/columns, aspect ratio control, built-in permission handling, and captured images with grid overlay.

License

Notifications You must be signed in to change notification settings

sagarkalel/grid_camera

Repository files navigation

grid_camera

pub package likes popularity

grid_camera is a Flutter package that enhances the camera experience with a customizable grid overlay system. Built on top of the official camera plugin, it provides an easy-to-use widget for applications requiring precise photo composition, document scanning, or grid-based image capture.

A Flutter camera package that provides a customizable grid overlay for precise photo composition. Features include adjustable grid rows/columns, aspect ratio control, built-in permission handling, and captured images with grid overlay. Perfect for applications requiring precise photo composition, document scanning, or grid-based image capture.

Key Features:

  • Customizable camera preview with adjustable grid overlay
  • Configurable grid rows, columns, and appearance
  • Flexible aspect ratio control
  • Built-in permission handling with customizable UI
  • Image capture with grid overlay
  • Utility extensions for quick widget styling
  • Responsive design and error handling
  • Easy integration with existing Flutter apps

Perfect for:

  • πŸ“Έ Document scanning apps
  • πŸ“Š Technical photography
  • πŸ“ Measurement applications
  • 🎨 Design and composition tools
  • πŸ“± Any app requiring precise photo capture

Features

  • πŸ“Έ Customizable camera preview with grid overlay
  • 🎯 Adjustable grid rows and columns
  • πŸ“ Configurable aspect ratio
  • 🎨 Customizable grid appearance
  • πŸ“± Built-in permission handling
  • πŸ”„ Image capture with grid overlay
  • ⚑ Utility extensions for quick widget styling
  • 🎯 Gap widget for consistent spacing
  • πŸ“± Platform Support:
    • βœ… Android
    • βœ… iOS

Getting Started

Prerequisites

This package relies on the official camera plugin. You'll need to configure your project according to the platform-specific requirements.

Android

Add the following permissions to your AndroidManifest.xml:

<uses-permission android:name="android.permission.CAMERA" />

iOS

Add the following keys to your Info.plist:

<key>NSCameraUsageDescription</key>
<string>Your camera usage description here</string>

For detailed camera setup instructions, please refer to the official camera plugin documentation.

Installation

Add this to your package's pubspec.yaml file:

dependencies:
  grid_camera: ^0.1.0

Usage

Complete Example

import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:grid_camera/grid_camera.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      themeMode: ThemeMode.dark,
      darkTheme: ThemeData.dark(),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  Uint8List? imageInBytes;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              "Grid Camera Demo",
              style: Theme.of(context).textTheme.titleLarge,
            ),
            const Gap(24),
            Container(
              height: MediaQuery.of(context).size.width * .8,
              width: MediaQuery.of(context).size.width * .8,
              decoration: BoxDecoration(
                color: Theme.of(context).primaryColorLight.withOpacity(0.5),
                borderRadius: BorderRadius.circular(10),
                image: imageInBytes == null
                    ? null
                    : DecorationImage(image: MemoryImage(imageInBytes!)),
              ),
              alignment: Alignment.center,
              child: imageInBytes != null
                  ? IconButton.outlined(
                      onPressed: () {
                        imageInBytes = null;
                        setState(() {});
                      },
                      icon: const Icon(Icons.delete_forever, size: 48),
                    )
                  : IconButton.outlined(
                      onPressed: () async {
                        final img = await Navigator.push(
                          context,
                          MaterialPageRoute(
                              builder: (context) => const CameraPage()),
                        );
                        if (img == null) return;
                        imageInBytes = img;
                        setState(() {});
                      },
                      icon: const Icon(Icons.upload, size: 48),
                    ),
            ),
            const Gap(kToolbarHeight),
          ],
        ).padXXDefault,
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return GridCameraWidget(
      onDonePressed: (Uint8List img) => Navigator.pop(context, img),
      rowCount: 10,
      columnCount: 10,
      gridWidth: 0.5,
      aspectRatio: 1 / 1,
    );
  }
}

Customized Implementation

GridCameraWidget(
  rowCount: 4,
  columnCount: 4,
  gridColor: Colors.white,
  gridWidth: 2.0,
  aspectRatio: 4/3,
  clickPhotoIcon: Icon(Icons.camera),
  doneIcon: Icon(Icons.check_circle),
  refreshIcon: Icon(Icons.refresh),
  cameraLoadingWidget: CircularProgressIndicator(),
  onDonePressed: (imageBytes) {
    // Handle captured image
  },
  onCameraAccessDenied: () {
    // Handle permission denied
  },
  otherExceptionTitleText: 'Custom Error Title',
  otherExceptionBodyText: 'Custom error message',
  otherExceptionOkayText: 'Retry',
);

Additional Utilities

Gap Widget

A simple widget for creating consistent spacing:

// Creates both vertical and horizontal space
const Gap(16);

// In a column
Column(
  children: [
    Text('Hello'),
    Gap(8),  // 8.0 pixels of space
    Text('World'),
  ],
);

Widget Extensions

Convenient extensions for common padding patterns:

// Horizontal padding
myWidget.padXX(16)

// Vertical padding
myWidget.padYY(16)

// Default horizontal padding (16px)
myWidget.padXXDefault

// Bottom padding
myWidget.padYBottom(16)

// Top padding
myWidget.padYTop(16)

// Left padding
myWidget.padXLeft(16)

// Right padding
myWidget.padXRight(16)

// All-side padding
myWidget.padAll(16)

// Expand widget
myWidget.expand

Configuration Options

GridCameraWidget Properties

Property Type Description
rowCount int Number of horizontal grid lines + 1
columnCount int Number of vertical grid lines + 1
gridColor Color? Color of grid lines
gridWidth double Width of grid lines
aspectRatio double Camera preview aspect ratio
onDonePressed Function(Uint8List) Callback when image is captured
onCameraAccessDenied VoidCallback? Callback when camera permission denied
onOtherException VoidCallback? Callback for other errors
permissionDeniedWidget Widget? Custom widget for permission denied state
cameraLoadingWidget Widget? Custom loading widget
clickPhotoIcon Widget? Custom capture button icon
doneIcon Widget? Custom done button icon
refreshIcon Widget? Custom refresh button icon
otherExceptionTitleText String? Custom error dialog title
otherExceptionBodyText String? Custom error dialog message
otherExceptionOkayText String? Custom error dialog button text

Troubleshooting

Common issues and their solutions:

  1. Camera not initializing: Ensure you've added all required permissions and followed the camera plugin setup.
  2. Black screen: Check if the camera permission is granted at runtime.
  3. Grid not visible: Verify that the gridColor contrasts with your camera preview.
  4. gradle error: To overcome this problem, you'll need to upgrade gradle version to latest version OR uou can use "grid_camera" package's old version (e.g grid_camera: ^0.0.8).

For more specific camera-related issues, please refer to the camera plugin's troubleshooting guide.

Contributing

Contributions are welcome! If you find a bug or want a feature, please file an issue.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Credits

This package builds upon the camera package, gives grid overlay and easy way to use camera widget.

About

A Flutter camera package that provides a customizable grid overlay for precise photo composition. Features include adjustable grid rows/columns, aspect ratio control, built-in permission handling, and captured images with grid overlay.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages