Skip to content

Instantly share code, notes, and snippets.

@lukepighetti
Last active June 24, 2019 20:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lukepighetti/3a3325a74f50567b2b4f83e7e102849b to your computer and use it in GitHub Desktop.
Save lukepighetti/3a3325a74f50567b2b4f83e7e102849b to your computer and use it in GitHub Desktop.
/*
* QR.Flutter
* Copyright (c) 2019 the QR.Flutter authors.
* See LICENSE for distribution and usage details.
*/
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:qr/qr.dart';
import 'painter.dart';
typedef ErrorBuilder = Widget Function(BuildContext context, dynamic error);
class QrImage extends StatelessWidget {
final String data;
final ErrorBuilder errorBuilder;
final Color foregroundColor;
final Color backgroundColor;
final EdgeInsets padding;
final double size;
final bool gapless;
final int version;
final int errorCorrectionLevel;
QrImage({
@required this.data,
this.errorBuilder,
Key key,
this.size,
this.padding = const EdgeInsets.all(10.0),
this.backgroundColor,
this.foregroundColor = const Color(0xFF000000),
this.version = 4,
this.errorCorrectionLevel = QrErrorCorrectLevel.L,
this.gapless = true,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final qr = QrCode(version, errorCorrectionLevel);
bool hasError = false;
dynamic error;
try {
qr.addData(data);
qr.make();
hasError = false;
} catch (e) {
hasError = true;
error = e;
}
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
final double widgetSize = size ?? constraints.biggest.shortestSide;
return Container(
width: widgetSize,
height: widgetSize,
color: backgroundColor,
child: Padding(
padding: padding,
child: hasError
? errorBuilder(context, error)
: CustomPaint(
painter: QrPainter(
qr: qr,
color: foregroundColor,
gapless: gapless,
),
),
),
);
},
);
}
}
import 'package:flutter/material.dart';
import 'image.dart' show QrImage;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Sandbox',
home: Scaffold(
body: SafeArea(
child: Center(
child: _Home(),
),
),
),
);
}
}
class _Home extends StatefulWidget {
@override
__HomeState createState() => __HomeState();
}
class __HomeState extends State<_Home> {
bool hasError = false;
_toggleError() {
setState(() {
hasError = !hasError;
});
}
@override
Widget build(BuildContext context) {
print(hasError);
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
QrImage(
data: !hasError
? "yo"
: "yo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79fyo9s87df8s79f",
size: 128,
errorBuilder: (_, e) => Text("error! $e"),
),
RaisedButton(
onPressed: _toggleError,
child: Text("Toggle error"),
)
],
);
}
}
/*
* QR.Flutter
* Copyright (c) 2019 the QR.Flutter authors.
* See LICENSE for distribution and usage details.
*/
import 'dart:async';
import 'dart:ui' as ui;
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:qr/qr.dart';
typedef QrError = void Function(dynamic error);
class QrPainter extends CustomPainter {
QrPainter({
@required this.qr,
this.color = const Color(0xff000000),
this.emptyColor,
this.gapless = false,
});
final Color color; // the color of the dark squares
final Color emptyColor; // the other color
final bool gapless;
final QrCode qr; // our qr code data
final Paint _paint = Paint()..style = PaintingStyle.fill;
QrCode get _qr => qr;
@override
void paint(Canvas canvas, Size size) {
assert(size.shortestSide != 0,
"[QR] WARN: width or height is zero. You should set a 'size' value or nest this painter in a Widget that defines a non-zero size");
if (emptyColor != null) {
canvas.drawColor(emptyColor, BlendMode.color);
}
final double squareSize = size.shortestSide / _qr.moduleCount.toDouble();
final int pxAdjustValue = gapless ? 1 : 0;
for (int x = 0; x < _qr.moduleCount; x++) {
for (int y = 0; y < _qr.moduleCount; y++) {
if (_qr.isDark(y, x)) {
final Rect squareRect = Rect.fromLTWH(x * squareSize, y * squareSize,
squareSize + pxAdjustValue, squareSize + pxAdjustValue);
canvas.drawRect(squareRect, _paint);
}
}
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
if (oldDelegate is QrPainter) {
return color != oldDelegate.color || _qr != oldDelegate._qr;
}
return false;
}
ui.Picture toPicture(double size) {
final ui.PictureRecorder recorder = ui.PictureRecorder();
final Canvas canvas = Canvas(recorder);
paint(canvas, Size(size, size));
return recorder.endRecording();
}
Future<ByteData> toImageData(double size,
{ui.ImageByteFormat format = ui.ImageByteFormat.png}) async {
final ui.Image uiImage =
await toPicture(size).toImage(size.toInt(), size.toInt());
return await uiImage.toByteData(format: format);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment