DEV Community

Cover image for Building a Text Recognition App in Flutter: Part 2 - Scanning and Cropping Images
raman04-byte
raman04-byte

Posted on • Originally published at raman04.hashnode.dev

Building a Text Recognition App in Flutter: Part 2 - Scanning and Cropping Images

Welcome back, fellow developers, to the second leg of our thrilling journey to create a Text Recognition App in Flutter! In the previous part, we set the stage by laying the foundation of our project and integrating essential packages. Now, it's time to explore the seas of image scanning and cropping before diving into Google ML Kit Text Recognition. Anchors aweigh!

Preparing for the Voyage
Before we embark on our coding adventure, let's ensure our ship is well-prepared. In Part 1, we covered the basics, including project setup and package integration. In this part, we'll expand our horizons and delve into image selection and cropping, two essential steps before we can harness the power of text recognition.

Navigating the Code
The main.dart File: Setting the Course
Our main.dart file is the captain of our ship, steering us in the right direction. It's responsible for setting up the app's theme and home screen.

import 'package:flutter/material.dart';
import 'package:google_mlkit_text_recognition/google_mlkit_text_recognition.dart';
import 'package:image_picker/image_picker.dart';
import 'package:tts_f/imagewithlines.dart';
import 'package:tts_f/utils/imagepicker.dart';
import 'package:tts_f/utils/textrecognizer.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

Enter fullscreen mode Exit fullscreen mode

The MyHomePage Widget: Scanning the Horizon
In our MyHomePage widget, we present the user with the option to select an image, either from the camera or gallery. We then pass this image for text recognition.

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

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

class _MyHomePageState extends State<MyHomePage> {
  String imagePath = "";
  List<TextBlock> textBlock = [];

  void _showModalSheet() {
    showModalBottomSheet(
      context: context,
      builder: (BuildContext context) {
        return Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            ListTile(
              leading: const Icon(Icons.camera),
              title: const Text('Camera'),
              onTap: () async {
                String path = await imagePickers(context, ImageSource.camera);
                setState(() {
                  imagePath = path;
                });
                await textRecognizer(path).then((value) {
                  textBlock = value;
                });
                Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => ImageWithTextLines(
                      imagePath: imagePath,
                      textBlock: textBlock,
                    ),
                  ),
                );
              },
            ),
            ListTile(
              leading: const Icon(Icons.browse_gallery),
              title: const Text('Gallery'),
              onTap: () async {
                String path = await imagePickers(context, ImageSource.gallery);
                setState(() {
                  imagePath = path;
                });
                await textRecognizer(path).then((value) {
                  textBlock = value;
                });
                Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => ImageWithTextLines(
                      imagePath: imagePath,
                      textBlock: textBlock,
                    ),
                  ),
                );
              },
            ),
          ],
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: const Center(
          child: Text('Select Image'),
        ),
        floatingActionButton: FloatingActionButton.extended(
          onPressed: _showModalSheet,
          label: const Text('Scan'),
        ),
      ),
    );
  }
}

Enter fullscreen mode Exit fullscreen mode

The imagepicker.dart File: Selecting the Perfect Image
This utility file provides a function to choose an image using the image_picker package and then sends it for cropping.

import 'package:image_picker/image_picker.dart';
import 'package:tts_f/utils/imagecropper.dart';

Future<String> imagePickers(context, ImageSource source) async {
  final ImagePicker picker = ImagePicker();
  final XFile? image = await picker.pickImage(source: source);
  String path = await croppedfile(context, image!.path);
  return path;
}

Enter fullscreen mode Exit fullscreen mode

The imagecropper.dart File: Crafting the Perfect Shot
Our image cropper utility uses the image_cropper package to let users crop their selected images for a better text recognition experience.

import 'package:flutter/material.dart';
import 'package:image_cropper/image_cropper.dart';
import 'dart:async';

Future<String> croppedfile(context, String imagePath) async {
  CroppedFile? croppedFile = await ImageCropper().cropImage(
    sourcePath: imagePath,
    aspectRatioPresets: [
      CropAspectRatioPreset.square,
      CropAspectRatioPreset.ratio3x2,
      CropAspectRatioPreset.original,
      CropAspectRatioPreset.ratio4x3,
      CropAspectRatioPreset.ratio16x9,
    ],
    uiSettings: [
      AndroidUiSettings(
        toolbarTitle: 'Cropper',
        toolbarColor: Colors.deepOrange,
        toolbarWidgetColor: Colors.white,
        initAspectRatio: CropAspectRatioPreset.original,
        lockAspectRatio: false,
      ),
      IOSUiSettings(
        title: 'Cropper',
      ),
      WebUiSettings(
        context: context,
      ),
    ],
  );
  return croppedFile!.path;
}

Enter fullscreen mode Exit fullscreen mode

Setting Sail for Text Recognition
With our image scanning and cropping mechanisms in place, we're now well-prepared for the next phase of our journey: text recognition using Google ML Kit. In the upcoming chapters, we'll dive into text recognition, language translation, and even text-to-speech functionality. So, stay tuned for the next thrilling installment of our Flutter Text Recognition App series!

Happy coding and smooth sailing, fellow developers! βš“πŸ“ΈπŸ“–πŸš€

Video: https://youtu.be/FrcQquZeAsU (in Hindi)

Top comments (0)