How to convert users signature to base64 encoding in Dart

1.1k views Asked by At

I'm using the syncfusion_flutter_signaturepad package to let the user input their signature. Now, what I'm trying to achieve is to convert that signature to base64 format for our API. Here's what I have.

GlobalKey<SfSignaturePadState> _signaturePadKey = GlobalKey();
.....

final signatureData = await _signaturePadKey.currentState!.toImage();
final image = await signatureData.toByteData(format: ui.ImageByteFormat.png);

if (image != null) {
  final imageBytes = image.buffer.asUint8List();
  final decodedImage = img.decodeImage(imageBytes);
  //String encodedSignature = base64.encode(decodedImage); //decodedImage error The argument type 'Image?' can't be assigned to the parameter type 'List<int>'.
  print('Base64 encoded string: $decodedImage');
}

Printed result is

Base64 encoded string: Instance of 'Image'

I also tried this way but it's still not working.

ui.Image signatureData =
    await _signaturePadKey.currentState!.toImage();
ByteData? byteData = await signatureData.toByteData(
    format: ui.ImageByteFormat.png);
String imageEncoded =
    base64.encode(byteData!.buffer.asUint8List());

print("Encoded: $imageEncoded");

Result is :

Encoded: iVBORw0KGgoAAAANSUhEUgAAAYkAAAKQCAYAAABq7IZzAAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAABUGSURBVHic7d3NdRPZvofhf99159KJQCICmwhsRndoEYHlCGxHYDkCRAQWEbh62D2hiAB1BFZHQBGB7oAlHZvuH9gg+YvnWYt1uuljqcRAL3vv2rt+Wy6XywKAf/rzfx76CgB4vEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEA

That when I try to test it in online converter, it's not working.

EDIT Added mimetype:

String imageEncoded = "data:image/png;base64," +
                  base64.encode(byteData!.buffer.asUint8List());

But it's only a blank page, the signature is not there at all.

RESULT:

Encoded: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAYkAAAKQCAYAAABq7IZzAAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAABUGSURBVHic7d3NdRPZvofhf99159KJQCICmwhsRndoEYHlCGxHYDkCRAQWEbh62D2hiAB1BFZHQBGB7oAlHZvuH9gg+YvnWYt1uuljqcRAL3vv2rt+Wy6XywKAf/rzfx76CgB4vEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBIJACIRAKASCQAiEQCgEgkAIhEAoBI

Am I on the right track on trying to get the desired result? How can I attain my goal using the syncfusion_flutter_signaturepad flutter package?

2

There are 2 answers

0
ramedju On BEST ANSWER

Oh! Might be helpful to anyone, conversion is working fine, my default here is that I relied on the printdebug value. This one did not display all converted data so I have to add a temporary textfield to display generated value.

TextEditingController _textEditingController = TextEditingController();

//under save button
// ......
String imageEncoded = await "data:image/png;base64," +
                      base64.encode(byteData!.buffer.asUint8List());
_textEditingController.text = imageEncoded;

TextField(
  controller: _textEditingController,
  //this one holds all the necessary encryped data
),

Hope this one might help someone!

6
G3nt_M3caj On

You can use those method as utilities to convert images to base64 and viceversa.

Calling imageToByteData(passing a drawing image as parameter) then calling uint8ListTobase64String(passing data got before by previous method).

Anyway in comments you will find what is used for each method. I think those methods might be prototypes from which you can start to improve, based on your needs!

  import 'dart:ui' as UI;
  import 'package:image/image.dart' as drawing;
  import 'package:flutter/widgets.dart'; 

  // Then on your class... where inside are:

  // Convert byte-data to base64
  static String uint8ListTobase64String(Uint8List? data) =>
      data != null ? base64Encode(data) : "";
  
  // Convert base64 string to byte-data as Uint8List
  static Uint8List? base64StringToUint8List(String base64String) =>
      (base64String.isNotEmpty) ? base64Decode(base64String) : null;

  // Widget Image from a base64 string 
  static Image imageFromBase64String(String base64String) =>
        Image.memory(base64Decode(base64String));

  // Passing a "drawing" image as parameter then convert it in a well-encoded image and return byte-data as Uint8List
  static Future<Uint8List?> imageToByteData(drawing.Image imageSource) async {
    try {
      UI.Codec codec = await UI.instantiateImageCodec(drawing.encodePng(imageSource));
      UI.FrameInfo frameInfo = await codec.getNextFrame();
      ByteData? data = await frameInfo.image.toByteData(format: UI.ImageByteFormat.png);
      return data!.buffer.asUint8List();
    } catch (e) {
   //log(e.toString());
    }

    return null;
  }

Take in mind here is used also image.dart package. You can find more info about it here: https://pub.dev/packages/image. But, that doesn't mean all cannot be done without it..