0

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?

ramedju
  • 139
  • 9
  • Does this answer your question? [how to convert an image to base64 image in flutter?](https://stackoverflow.com/questions/50036393/how-to-convert-an-image-to-base64-image-in-flutter) – OMi Shah Apr 12 '23 at 08:35
  • @OMiShah Thank you, but that one was using image picker while mine here is I'm using signature pad. I'm not sure if toImage creates temp file path for the signature and how I can I possibly access if it does. – ramedju Apr 12 '23 at 08:41
  • you are missing prefix of mimetype... – G3nt_M3caj Apr 12 '23 at 08:43
  • @G3nt_M3caj Oh thanks for that one! But when I try to save it, it's just blank page, no signature at all . – ramedju Apr 12 '23 at 08:45
  • It is normal, base64 functionality is that without a specific output. – G3nt_M3caj Apr 12 '23 at 08:47
  • @G3nt_M3caj Oh! So if I convert it back to image, it will be just a blank image? Without the signature? – ramedju Apr 12 '23 at 08:51
  • I'm going to post an answer with utilities that you can use to do the correct conversion – G3nt_M3caj Apr 12 '23 at 08:54

2 Answers2

2

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..

G3nt_M3caj
  • 2,497
  • 1
  • 14
  • 16
  • Thanks for this. From what I've understood from imageToByteData is that it uses image path? If so, what I'm using here is from the signature of the user then directly convert it to base 64 encoding. – ramedju Apr 12 '23 at 09:16
  • imageToByteData use an Image as parameter by (package image.dart you can find it in flutter packages repo) . Anyway get your test, using parts that what you need – G3nt_M3caj Apr 12 '23 at 09:35
  • I see. This line of code `drawing.encodePng(imageSource)` showing an error `The argument type 'List' can't be assigned to the parameter type 'Uint8List'` – ramedju Apr 12 '23 at 09:43
  • Who List is coming from? Convert it directly as Uint8List before you will pass it... OR USE : `Uint8List.fromList(yourListHere)` – G3nt_M3caj Apr 12 '23 at 09:49
  • I have no idea where it came from, I just copied your code to test it and that line highlights with error. – ramedju Apr 12 '23 at 09:51
  • That because of your flutter version maybe. Use as I wrote in comment `Uint8List.fromList(yourListHere)` – G3nt_M3caj Apr 12 '23 at 09:52
1

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!

ramedju
  • 139
  • 9