4q-s-r-o / signature Goto Github PK
View Code? Open in Web Editor NEWFlutter plugin that creates a canvas for writing down a signature
License: MIT License
Flutter plugin that creates a canvas for writing down a signature
License: MIT License
I faced this error when I tried to save the image after generated :
E/flutter ( 3742): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: MissingPluginException(No implementation found for method saveImageToGallery on channel image_gallery_saver)
E/flutter ( 3742): #0 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:154:7)
E/flutter ( 3742):
E/flutter ( 3742): #1 ImageGallerySaver.saveImage (package:image_gallery_saver/image_gallery_saver.dart:20:9)
E/flutter ( 3742):
E/flutter ( 3742): #2 _GetdocsignState.build. (package:gsdoc_mobile_v2/getdoc/getdocsign.dart:207:60)
E/flutter ( 3742):
E/flutter ( 3742):
Hello! ✌️
Thank you for the package! Just thought that it would be really nice to see an example of it as a GIF in the readme.
Hi there,
at the moment controller.toImage() and .toPngBytes() return various size images, depending on the painted dots area.
Since the backend i have to upload signature images expects fixed size images i was wondering if it wouldn't be possible to let callers of those 2 methods define optional width and height parameters which (if defined) would be used as the size of the returned image, where the signature then is centered.
If the width and/or height are smaller than the signature those values would be used.
Or how could i reach this by myself after receiving a ui.Image from controller.toImage() ?
I would like to propose a feature for auto-generating the signature or prepopulating the SignaturePad's canvas by supplying an initial text.
Something like:
TextPainter _buildTextPainter(Size canvasSize) {
//Determins the scale of the generated text so it
//fits the most appropriatelly basen on it's length
final defaultScaleCharWidth = 9.0;
final maxCharacters = canvasSize.width / defaultScaleCharWidth;
final initialTextScaleFactor = maxCharacters / text.length;
final textScaleFactor = (initialTextScaleFactor == 0 ? 1 : initialTextScaleFactor) * 0.8;
//Define text style, maybe later add custom font that's more appropriate for a signature...
final span = TextSpan(
text: text,
style: const TextStyle(color: Colors.black, fontStyle: FontStyle.italic),
);
//Build the text painter to compute all the
//points that are required to render the text on canvas
final textPainter = TextPainter(
text: span,
textAlign: TextAlign.left,
textDirection: painting.TextDirection.ltr,
textScaleFactor: textScaleFactor,
);
textPainter.layout();
return textPainter;
}
// ...
final textPainter = _buildTextPainter(size);
textPainter.paint(
canvas,
Offset(
_horizontalOffset(size, textPainter),
_verticalOffset(size, textPainter),
),
);
Hi,
I want to export the signature to a pdf file. Is it possible to do that? And how could I implement it?
Thanks for helping me
Signing quickly on iOS or android makes the signature have gaps in-between points. Any idea what may be causing this?
When calling the toPngBytes
method, an exception is thrown:
Unhandled Exception: Exception: operation failed
This exception occurs at line 189 of signature.dart:
picture.toImage( (maxX - minX + penStrokeWidth * 2).toInt(), (maxY - minY + penStrokeWidth * 2).toInt());
Code for reproducing:
class _SomePageState extends State<SomePage> {
Signature signaturePad;
@override
void didChangeDependencies() {
super.didChangeDependencies();
signaturePage = Signature(
height: 300.0,
penColor: Theme.of(context).accentColor,
);
signaturePad.clear() // Here I have a crash "the method clear was called on null"
}
}
At break point I see that inner key
is null. It looks like createState
method is not called.
Hi,
I have used this plugin and it really helped me thank you for this work.
but I have a question which is how to stop listening to the signature widget for any painting.
I mean it will be unpaintable.
Thank you,
Please add support to export signature data as SVG.
I'm trying to save a png signature image in the internal directory, but it saves nothing.
How do I save the png signature file in the internal directory?
My code:
onPressed: () async {
if (_controller.isNotEmpty) {
final Uint8List? data = await _controller.toPngBytes();
if (data != null) {
Directory? directory = await getExternalStorageDirectory();
String path = directory!.path;
print(path);
var pngImage = await image.toByteData(format: _controller.ImageByteFormat.png);
await Directory('$path/assinaturaUser').create(recursive: true);
File('$path/$directoryName/$_controller').writeAsBytesSync(data.buffer.asUint8List());
final SharedPreferences prefs = await SharedPreferences.getInstance();
String base64Image = base64Encode(data);
prefs.setString("image", base64Image);
print(base64Image);
}
}
},
Hey
How I can export signature as a file ??? I need it for saving on a table.
Image.toByteData is not supported in Flutter for Web
The byte generation is failing on flutter web. I need a solution which works equally for web and the other platforms.
I managed it to get it work by using the package image
:
https://pub.dev/packages/image
It doesn't feel so right: For flutter web the signature points get redrawn with the image
package (I did it almost equally how you did with the normal canvas). So it feels a bit duplicated and with an additional package, but maybe it's a starting point.
I am using Flutter Channel dev, 1.20.0-1.0.pre
Error: Exception: operation failed
at Object.createErrorWithStack (http://localhost:59763/dart_sdk.js:4479:12)
at Object._rethrow (http://localhost:59763/dart_sdk.js:37395:16)
at async._AsyncCallbackEntry.new.callback (http://localhost:59763/dart_sdk.js:37389:13)
at Object._microtaskLoop (http://localhost:59763/dart_sdk.js:37221:13)
at _startMicrotaskLoop (http://localhost:59763/dart_sdk.js:37227:13)
at http://localhost:59763/dart_sdk.js:32849:9Error: Exception: Image.toByteData is not supported in Flutter for Web
at Object.throw_ [as throw] (http://localhost:59763/dart_sdk.js:4465:11)
at Object.futurize (http://localhost:59763/dart_sdk.js:166948:17)
at _engine.HtmlImage.new.toByteData (http://localhost:59763/dart_sdk.js:142412:22)
at signature.SignatureController.new.toPngBytes (http://localhost:59763/packages/signature/signature.dart.lib.js:792:34)
at toPngBytes.next (<anonymous>)
at http://localhost:59763/dart_sdk.js:37106:33
at _RootZone.runUnary (http://localhost:59763/dart_sdk.js:36960:58)
at _FutureListener.thenAwait.handleValue (http://localhost:59763/dart_sdk.js:32047:29)
at handleValueCallback (http://localhost:59763/dart_sdk.js:32594:49)
at Function._propagateToListeners (http://localhost:59763/dart_sdk.js:32632:17)
at _Future.new.[_completeWithValue] (http://localhost:59763/dart_sdk.js:32475:23)
at async._AsyncCallbackEntry.new.callback (http://localhost:59763/dart_sdk.js:32497:35)
at Object._microtaskLoop (http://localhost:59763/dart_sdk.js:37221:13)
at _startMicrotaskLoop (http://localhost:59763/dart_sdk.js:37227:13)
at http://localhost:59763/dart_sdk.js:32849:9
I have a api respose of signature in base64 String so how can I covert base64 string and pass the predefined signature to it's controller, is it possible
Please consider that would be nice to have the exportPenColor property. For black theming ideal penColor will probably be white, while exporting penColor should be black or darker color.
Thanks in advance,
S.
thank you
_controller.clear() doesn't work when called. The user must call the function and then start drawing again before it clears.
If i set signature inside expanded in row widget and don't specify width i am able to draw out side of signature widget.
For test purpose:
Row( children: [ Expanded(child: AutoSizeText("Citizen Signature")), Flexible( flex: 2, child: Signature( controller: SignatureController( penStrokeWidth: 5, penColor: Colors.black, exportBackgroundColor: Colors.blue, ), height: height * 0.1, backgroundColor: Colors.grey[300]!, ) ) ], )
Are you going to provide a null-safety version of this great plug-in?
Is there a way to export a signature image with transparent background? Thanks
Hi, I try to export a signature as a png byte but I always get this exception:
VERBOSE-2:dart_vm_initializer.cc(41)] Unhandled Exception: 'package:signature/signature.dart': Failed assertion: line 413 pos 9: '((width ?? defaultWidth!) - defaultWidth!) >= 0.0': Exported width cannot be smaller than actual width
This is my widget:
class SignaturePage extends StatefulWidget {
const SignaturePage({Key? key}) : super(key: key);
@override
State<SignaturePage> createState() => _SignaturePageState();
}
class _SignaturePageState extends State<SignaturePage> {
final SignatureController _controller = SignatureController(
penStrokeWidth: 5,
penColor: Colors.black,
exportBackgroundColor: Colors.transparent,
);
@override
Widget build(BuildContext context) {
return BlocBuilder<SendMeToTheMoonBloc, SendMeToTheMoonState>(
builder: (context, stateMoon) {
return Scaffold(
body: SafeArea(
child: Container(
padding: const EdgeInsets.only(top: 20, left: 15, right: 20),
child: BlocBuilder<SignOffBloc, SignOffState>(
builder: (context, state) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Thanks, ${state.signOffSigner!.firstName}.'),
const Text('Can you sign here to complete the job?'),
const SizedBox(height: 20),
LayoutBuilder(builder: (context, constraints) {
return ConstrainedBox(
constraints: BoxConstraints(
maxWidth: constraints.maxWidth,
maxHeight: 500,
),
child: Card(
child: Stack(
children: [
const Padding(
padding: EdgeInsets.all(8.0),
child: Text('Signature'),
),
Signature(
controller: _controller,
backgroundColor: Colors.transparent,
),
],
),
),
);
}),
Center(
child: ElevatedButton(
onPressed: () async {
final image = await _controller.toPngBytes();
if (image != null && mounted) {
final signature = UploadImage(
bucket: 'some_bucket',
filePath: 'some/path',
file: image,
);
context.read<SendMeToTheMoonBloc>().add(
SignatureSubmitted(
signature: signature,
),
);
}
},
child: const Icon(Icons.arrow_forward),
),
)
],
);
},
),
),
),
);
},
);
}
}
Is there something that I'm doing wrong when I wrap the signature?
Thanks!
[signature-teste] flutter pub get
Running "flutter pub get" in signature-teste...
Error on line 30, column 3 of pubspec.yaml: A package may not list itself as a dependency.
╷
30 │ signature: ^4.1.1
│ ^^^^^^^^^
╵
pub get failed (65; ╵)
exit code 65
Good work on this useful plugin.
Is there possibility of adding an onChanged(updatedData)
callback that will notify when user interaction has stopped sending back the byte data for users to react to?
If you put the signature widget in a tabbarpage and you try to swipe horizontal it will still swipe the entire tab and you can't draw.. Do you know any fix for that? ty!
Current version seems to draw points/lines with fixed penStrokeWidth. By utilizing the pressure property in PointEvent one could in theory capture and simulate a more realistic hand-written signature.
Hi,
after upgrading to 5.2.1 all my signatures are saved as 400x500px and cannot be resized.
I find this part of code:
//WIDTH AND HEIGHT IS OPTIONAL. IMAGE WILL BE CENTERED
final ui.Image? image = await toImage(height: 500, width: 400);
How can I use toPngBytes() to get an image in the proper size, based on image data?
In old version that part works fine.
I'm trying to save the signature to the Database, so i need to convert the signature which is current in pngbytes. But I need to show the saved image in a base64 format. So how to convert a pngbytes to base64?
Hi I'm looking to export the signature and send it to the server in a json string.
What is the best method to achieve this?
I was thinking..
Uint8List signature = await _signatureController.toPngBytes();
String signature64 = base64Encode(signature);
But this is giving me an error
Unhandled Exception: type '_InternalLinkedHashMap<String, String>' is not a subtype of type 'String'
how can i open a previous signature from bytes stored in a blob column in database?,
Im expecting something like _controller.fromBytes(Uint8List)
, but, i just found the _controller.points(List<Point>)
but i cant figure out how store this on db
It is not fixed. You still can draw outside of the boundaries to the right and to the bottom.
Hi have a form containing the signature.
When the form is submitted, the widget is replaced by an image. By doing so, the user cannot edit the signature anymore, during the submission (which can take few seconds).
Sadly, as the export method is more than linked to the drawing canvas, the export fails.
Hi,
One of our customers reported that changing the device orientations wipes or clears the signature they have added. This issue is happening only on iOS, android works fine.
Do you think it is a bug in the libraries, if so, do you have any recommendations for us until the issue is fixed?
Thanks
It will be great we can have a undo functionality so that users can undo their steps if they make any mistakes while drawing signature instead of reseting whole canvas.
I'm saving signature to server and server gives me an url. So kindly can you tell how can i show signature from url?
The user might accidentally touch the status bar like in the video, and the Listener object does not handle the cancellation callback, so the user can not continue drawing while this is happening.
Add Listener.onPointerCancel may solves this problem :
class SignatureState extends State<Signature> {
@override
Widget build(BuildContext context) {
...
Listener(
...
onPointerCancel: (PointerCancelEvent event) {
if (activePointerId == event.pointer) {
_addPoint(event, PointType.tap);
widget.controller.onDrawEnd?.call();
activePointerId = null;
}
},
);
}
}
Here are the results:
If the Signature
widget is part of a scrolling container, drawing gestures cause unwanted scrolling. My expectation is that drawing inside the widget will work just fine and the container doesn't scroll.
Attached is a simple example that demonstrates the problem. If you try to draw something inside the amber signature widget, the ListView
scrolls and subscribing is nearly impossible.
Perhaps using a GestureDetector
instead of a Listener
widget would help?
I'm currently using the signature plugin in order to create writing data which will be sent to an API.
This API requires me to timestamp every point, and this is not possible without a callback on the onPointerMove
method.
This is a breaking change as noted here
Here is the error message and backtrace:
[VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: 'package:signature/signature.dart': error: file:///Users/steven/flutter/.pub-cache/hosted/pub.dartlang.org/signature-1.0.3/lib/signature.dart:201:29: Error: The method 'toByteData' isn't defined for the class 'Future<Image>'.
- 'Future' is from 'dart:async'.
- 'Image' is from 'dart:ui'.
Try correcting the name to the name of an existing method, or defining a method named 'toByteData'.
var bytes = await image.toByteData(format: ImageByteFormat.png);
^^^^^^^^^^
#0 _AsyncAwaitCompleter.start (dart:async/runtime/libasync_patch.dart:49:6)
#1 _SignaturePainter.export (package:signature/signature.dart:187:27)
#2 SignatureState.exportBytes (package:signature/signature.dart:65:26)
<asynchronous suspension>
#3 Signature.exportBytes (package:signature/signature.dart:34:35)
<asynchronous suspension>
#4 Drawable.build.<anonymous closure> (package:zboviq/pages/shared/drawable.dart:81:74)
#5 _InkRe<…>
[VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: 'package:signature/signature.dart': error: file:///Users/steven/flutter/.pub-cache/hosted/pub.dartlang.org/signature-1.0.3/lib/signature.dart:201:29: Error: The method 'toByteData' isn't defined for the class 'Future<Image>'.
- 'Future' is from 'dart:async'.
- 'Image' is from 'dart:ui'.
Try correcting the name to the name of an existing method, or defining a method named 'toByteData'.
var bytes = await image.toByteData(format: ImageByteFormat.png);
^^^^^^^^^^
#0 _AsyncAwaitCompleter.start (dart:async/runtime/libasync_patch.dart:49:6)
#1 _SignaturePainter.export (package:signature/signature.dart:187:27)
#2 SignatureState.exportBytes (package:signature/signature.dart:65:26)
<asynchronous suspension>
#3 Signature.exportBytes (package:signature/signature.dart:34:35)
<asynchronous suspension>
#4 Drawable.build.<anonymous closure> (package:zboviq/pages/shared/drawable.dart:81:74)
#5 _InkRe<…>
The assignment at line 157 has no effect.
Consider the following example app:
import 'package:flutter/material.dart';
import 'package:signature/signature.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final SignatureController controller = SignatureController();
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Signature Demo',
home: Scaffold(
appBar: AppBar(),
body: Stack(
children: [
Signature(
controller: controller,
backgroundColor: Colors.black12,
),
IconButton(
icon: Icon(Icons.delete),
onPressed: () => controller.clear(),
)
],
),
),
);
}
}
When drawing, the console keeps spitting out this error message:
Another exception was thrown: Incorrect use of ParentDataWidget.
After looking a little bit around, I found that the causing line was the last part of the build function of SignatureState
:
if (widget.width != null || widget.height != null) {
//IF DOUNDARIES ARE DEFINED, USE LIMITED BOX
return Center(
child: LimitedBox(
maxWidth: maxWidth,
maxHeight: maxHeight,
child: signatureCanvas,
),
);
} else {
//IF NO BOUNDARIES ARE DEFINED, USE EXPANDED
return Expanded(child: signatureCanvas);
}
Wrapping the canvas inside an Expanded
widget only makes sense if the canvas is a child of Column
, Row
or Flex
. See StackOverflow.
Although Expanded
is needed when wrapped inside either of those three widgets, I think it would be better to let the user decide if the canvas should be expanded or not.
Would it be possible to modify the shape of the signature container to be a circle as well as in the image of the signature saved?
If i accidentally tap on screen while drawing it draws a line between this two points. Can i disable multitap?
Hi i have the following code.
if (_signatureCanvas.isEmpty) {
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text(
'Error could not save signed document. Please sign before saving'),
duration: Duration(seconds: 3),
),
);
} else {
print('1');
_signatureCanvas.exportBytes().then((bytes) {
print(bytes);
_service.setSignature(bytes);
_service.submitSignature();
}).catchError((e) {
print(e);
});
print('2');
}
The exportBytes is not working and only 1 and 2 is printed
flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel beta, v1.12.13+hotfix.6, on Microsoft Windows [Version 10.0.18362.535], locale en-ZA)
[√] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[√] Chrome - develop for the web
[!] Android Studio (version 3.1)
X Flutter plugin not installed; this adds Flutter specific functionality.
X Dart plugin not installed; this adds Dart specific functionality.
[√] VS Code, 64-bit edition (version 1.41.1)
[√] Connected device (2 available)
! Doctor found issues in 1 category.
Running Flutter web though
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.