How to Add a Digital Signature in SfPdfViewer Using SfSignaturePad?
In this example, we have added the signature drawn on the SfSignaturePad to the document in SfPdfViewer with the help of the Syncfusion® PDF Library.
In the _handleSigningProcess() method, the signature in the SfSignaturePad is saved as an image using the toImage() method. A PdfSignatureField() is created, and the signature image is added as a digital signature in the PDF document using the drawImage() method in the Syncfusion® PDF Library, then saving the document as bytes. The saved document bytes are loaded using the SfPdfViewer.memory(). The following code example explains the same.
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:syncfusion_flutter_pdf/pdf.dart';
import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart';
import 'package:syncfusion_flutter_signaturepad/signaturepad.dart';
void main() {
return runApp(const SignaturePadApp());
}
class SignaturePadApp extends StatelessWidget {
const SignaturePadApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: _MyHomePage(),
);
}
}
@immutable
class _MyHomePage extends StatefulWidget {
const _MyHomePage({super.key});
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<_MyHomePage> {
final GlobalKey<SfSignaturePadState> _signaturePadGlobalKey = GlobalKey();
Uint8List? _documentBytes;
@override
void initState() {
super.initState();
_loadDocument();
}
Future<void> _loadDocument() async {
final ByteData docBytes = await rootBundle.load("assets/sample.pdf");
_documentBytes = docBytes.buffer.asUint8List();
setState(() {});
}
// Add the signature in the PDF document.
void _handleSigningProcess() async {
// Save the signature as a PNG image.
final data =
await _signaturePadGlobalKey.currentState!.toImage(pixelRatio: 3.0);
final bytes = await data.toByteData(format: ui.ImageByteFormat.png);
final ByteData docBytes = await rootBundle.load("assets/sample.pdf");
final Uint8List documentBytes = docBytes.buffer.asUint8List();
ByteData certBytes = await rootBundle.load("assets/certificate.pfx");
final Uint8List certificateBytes = certBytes.buffer.asUint8List();
// Load the document
PdfDocument document = PdfDocument(inputBytes: documentBytes);
// Get the first page of the document. The page where the signature needs to be added.
PdfPage page = document.pages[0];
// Create a digital signature and set the signature information.
PdfSignatureField signatureField = PdfSignatureField(page, 'signature',
bounds: const Rect.fromLTRB(300, 500, 550, 700),
signature: PdfSignature(
// Create a certificate instance from the PFX file with a private key.
certificate: PdfCertificate(certificateBytes, 'password123'),
contactInfo: '[email protected]',
locationInfo: 'Honolulu, Hawaii',
reason: 'I am the author of this document.',
digestAlgorithm: DigestAlgorithm.sha256,
cryptographicStandard: CryptographicStandard.cms));
// Get the signature field appearance graphics.
PdfGraphics? graphics = signatureField.appearance.normal.graphics;
// Draw the signature image on the PDF page.
graphics?.drawImage(PdfBitmap(bytes!.buffer.asUint8List()),
const Rect.fromLTWH(0, 0, 250, 200));
// Add a signature field to the form.
document.form.fields.add(signatureField);
_documentBytes = Uint8List.fromList(document.saveSync());
document.dispose();
setState(() {});
}
// Clear the signature in the SfSignaturePad.
void _handleClearButtonPressed() {
_signaturePadGlobalKey.currentState!.clear();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('PDF Viewer with Signature Pad'),
),
body: Column(
children: [
Expanded(
child: _documentBytes != null
? SfPdfViewer.memory(
_documentBytes!,
)
: const Center(child: CircularProgressIndicator()),
),
Container(
height: 170,
decoration: BoxDecoration(border: Border.all(color: Colors.grey)),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
height: 100,
width: 300,
decoration:
BoxDecoration(border: Border.all(color: Colors.grey)),
child: SfSignaturePad(
key: _signaturePadGlobalKey,
backgroundColor: Colors.white,
strokeColor: Colors.black,
minimumStrokeWidth: 1.0,
maximumStrokeWidth: 4.0),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 30, 0),
child: ElevatedButton(
onPressed: _handleSigningProcess,
child:
const Text('Add Signature and Load the Document'),
),
),
ElevatedButton(
onPressed: _handleClearButtonPressed,
child: const Text('Clear'),
),
],
)
],
),
)
],
));
}
}
To learn more about adding a digital signature to a PDF document, please refer here.