Search code examples
flutterflutter-dependenciesimagepicker

Convert images clicked from your phone to pdf in flutter using image_clicker and pdf package


I am clicking images using the image_picker package and the images are returned as a File Type, I am storing all the images I click in a list of type File( because image_picker is returning a File ). Now i want to convert all the images into one pdf, for this i am using the pdf package. So, how do i do that, in the documentation they showed the way only for Text and Image, i need to know how to add files in a pdf.

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'dart:io';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  List<File> _files = [];
  final pdf = pw.Document();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Home"),
        centerTitle: true,
      ),
      body: Stack(
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: new GridView.builder(
              itemCount: _files.length,
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 3,
              ),
              itemBuilder: (context, index) {
                return displaySelectedFile(_files[index]);
              },
            ),
          ),
          Positioned(
            left: 30.0,
            bottom: 18.0,
            child: RaisedButton(
              onPressed: () {
                for (var i = 0; i < _files.length; i++) {
                  pdf.addPage(pw.Page(
                      pageFormat: PdfPageFormat.a4,
                      build: (pw.Context context) {
                        return pw.Center(child: pw.Image(_files[i]));
                      }));
                }
              },
              color: Colors.blue,
              child: Text(
                'Get PDF',
                style: TextStyle(color: Colors.white),
              ),
            ),
          ),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          File cameraFile;
          print('Pressed');
          cameraFile = await ImagePicker.pickImage(source: ImageSource.camera);
          print(cameraFile.path);
          List<File> temp = _files;
          temp.add(cameraFile);
          setState(() {
            _files = temp;
          });
        },
        child: Icon(Icons.camera_alt),
      ),
    );
  }

  Widget displaySelectedFile(File file) {
    return Padding(
      padding: const EdgeInsets.all(4.0),
      child: SizedBox(
        height: 200.0,
        width: 200.0,
        child: Image.file(file),
      ),
    );
  }
}

this is my pubspec.yaml

name: prototype
description: A new Flutter project.

# The following line prevents the package from being accidentally published to
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev

# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1

environment:
  sdk: ">=2.7.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  image_picker: ^0.6.7+3
  pdf: ^1.9.0


  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.3

dev_dependencies:
  flutter_test:
    sdk: flutter

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

# The following section is specific to Flutter.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  # To add assets to your application, add an assets section, like this:
  # assets:
  #   - images/a_dot_burr.jpeg
  #   - images/a_dot_ham.jpeg

  # An image asset can refer to one or more resolution-specific "variants", see
  # https://flutter.dev/assets-and-images/#resolution-aware.

  # For details regarding adding assets from package dependencies, see
  # https://flutter.dev/assets-and-images/#from-packages

  # To add custom fonts to your application, add a fonts section here,
  # in this "flutter" section. Each entry in this list should have a
  # "family" key with the font family name, and a "fonts" key with a
  # list giving the asset and other descriptors for the font. For
  # example:
  # fonts:
  #   - family: Schyler
  #     fonts:
  #       - asset: fonts/Schyler-Regular.ttf
  #       - asset: fonts/Schyler-Italic.ttf
  #         style: italic
  #   - family: Trajan Pro
  #     fonts:
  #       - asset: fonts/TrajanPro.ttf
  #       - asset: fonts/TrajanPro_Bold.ttf
  #         weight: 700
  #
  # For details regarding fonts from package dependencies,
  # see https://flutter.dev/custom-fonts/#from-packages

Solution

  • try this

    import 'package:flutter/material.dart';
    import 'package:image_picker/image_picker.dart';
    import 'dart:io';
    import 'package:pdf/pdf.dart';
    import 'package:pdf/widgets.dart' as pw;
    
    class Home extends StatefulWidget {
      @override
      _HomeState createState() => _HomeState();
    }
    
    class _HomeState extends State<Home> {
      List<File> _files = [];
      final pdf = pw.Document();
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("Home"),
            centerTitle: true,
          ),
          body: Stack(
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: new GridView.builder(
                  itemCount: _files.length,
                  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 3,
                  ),
                  itemBuilder: (context, index) {
                    return displaySelectedFile(_files[index]);
                  },
                ),
              ),
              Positioned(
                left: 30.0,
                bottom: 18.0,
                child: RaisedButton(
                  onPressed: () {
    
                    for (var i = 0; i < _files.length; i++) {
                     // added this
                      var image = PdfImage.file(
                         pdf.document,
                         bytes: File(_files[i].path).readAsBytesSync(),
                       );
    
                      pdf.addPage(pw.Page(
                          pageFormat: PdfPageFormat.a4,
                          build: (pw.Context context) {
                            return pw.Center(child: pw.Image(image);
                          }));
                    }
                  },
                  color: Colors.blue,
                  child: Text(
                    'Get PDF',
                    style: TextStyle(color: Colors.white),
                  ),
                ),
              ),
            ],
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () async {
              File cameraFile;
              print('Pressed');
              cameraFile = await ImagePicker.pickImage(source: ImageSource.camera);
              print(cameraFile.path);
              List<File> temp = _files;
              temp.add(cameraFile);
              setState(() {
                _files = temp;
              });
            },
            child: Icon(Icons.camera_alt),
          ),
        );
      }
    
      Widget displaySelectedFile(File file) {
        return Padding(
          padding: const EdgeInsets.all(4.0),
          child: SizedBox(
            height: 200.0,
            width: 200.0,
            child: Image.file(file),
          ),
        );
      }
    }