- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想让用户有机会在 CustomPaint
上使用手机创建多边形。对于此功能,还涉及 GestureDetector
。正在使用 ImagePicker
库从文件加载图像。这里的问题是如何将 Canvas 和手势检测器调整为图片的大小。有什么想法吗?
Code: `import 'dart:io';
import 'dart:math';
import 'dart:ui' as ui;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:image_picker/image_picker.dart';
import 'package:listassist/services/auth.dart';
class PictureShow extends StatefulWidget {
@override
_PictureShowState createState() => _PictureShowState();
}
class _PictureShowState extends State<PictureShow> {
ui.Image _image;
Image _imageWidget;
List<ui.Offset> _points = [ui.Offset(90, 120), ui.Offset(90, 370), ui.Offset(320, 370), ui.Offset(320, 120)];
bool _clear = false;
int _currentlyDraggedIndex = -1;
@override
Widget build(BuildContext context) {
final AppBar appBar = AppBar(
backgroundColor: Theme.of(context).colorScheme.primary,
title: Text("Rechungserkennung"),
);
return Scaffold(
floatingActionButton:
FloatingActionButton(
child: Icon(Icons.clear),
onPressed: () {
setState(() {
_clear = true;
_points = [];
});
}
),
appBar: appBar,
backgroundColor: _imageWidget != null ? Colors.black : Colors.white,
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
if (_imageWidget == null) ...[
FlatButton(
onPressed: () => _pickImage(ImageSource.camera),
color: Colors.blueAccent,
padding: EdgeInsets.all(40.0),
child: Column(
children: <Widget>[
Icon(Icons.camera_alt, color: Colors.white,),
Text("Aus der Kamera", style: TextStyle(color: Colors.white),)
],
),
),
Padding(
padding: const EdgeInsets.only(top: 40, bottom: 40),
child: Text("oder", textScaleFactor: 2,),
),
FlatButton(
onPressed: () => _pickImage(ImageSource.gallery),
color: Colors.brown,
padding: EdgeInsets.all(40.0),
child: Column(
children: <Widget>[
Icon(Icons.photo, color: Colors.white,),
Text("Aus der Gallerie", style: TextStyle(color: Colors.white),)
],
),
),
],
if (_imageWidget != null) ...[
GestureDetector(
onPanStart: (DragStartDetails details) {
// get distance from points to check if is in circle
int indexMatch = -1;
for (int i = 0; i < _points.length; i++) {
double distance = sqrt(pow(details.localPosition.dx - _points[i].dx, 2) + pow(details.localPosition.dy - _points[i].dy, 2));
if (distance <= 30) {
indexMatch = i;
break;
}
}
if (indexMatch != -1) {
_currentlyDraggedIndex = indexMatch;
}
},
onPanUpdate: (DragUpdateDetails details) {
if (_currentlyDraggedIndex != -1) {
setState(() {
_points = List.from(_points);
_points[_currentlyDraggedIndex] = details.localPosition;
});
}
},
onPanEnd: (_) {
setState(() {
_currentlyDraggedIndex = -1;
});
},
child: CustomPaint(
size: Size.fromHeight(MediaQuery.of(context).size.height - appBar.preferredSize.height),
painter: RectanglePainter(points: _points, clear: _clear, image: _image),
),
)
]
],
),
);
}
Future _pickImage(ImageSource imageSource) async {
try {
File imageFile = await ImagePicker.pickImage(source: imageSource);
ui.Image finalImg = await _load(imageFile.path);
setState(() {
_imageWidget = Image.file(imageFile);
_image = finalImg;
});
} on Exception {
ResultHandler
.showInfoSnackbar(Text("Ein Fehler ist aufgetreten beim Öffnen des Bildes. Die App benötigt Zugriff auf die Galerie"));
}
}
Future<ui.Image> _load(String asset) async {
ByteData data = await rootBundle.load(asset);
ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List());
ui.FrameInfo fi = await codec.getNextFrame();
return fi.image;
}
}
class RectanglePainter extends CustomPainter {
List<Offset> points;
bool clear;
final ui.Image image;
RectanglePainter({@required this.points, @required this.clear, @required this.image});
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.red
..strokeCap = StrokeCap.square
..style = PaintingStyle.fill
..strokeWidth = 2;
final outputRect = Rect.fromPoints(ui.Offset.zero, ui.Offset(size.width, size.height));
final Size imageSize = Size(image.width.toDouble(), image.height.toDouble());
final FittedSizes sizes = applyBoxFit(BoxFit.contain, imageSize, outputRect.size);
final Rect inputSubrect = Alignment.center.inscribe(sizes.source, Offset.zero & imageSize);
final Rect outputSubrect = Alignment.center.inscribe(sizes.destination, outputRect);
canvas.drawImageRect(image, inputSubrect, outputSubrect, paint);
if (!clear) {
final circlePaint = Paint()
..color = Colors.red
..strokeCap = StrokeCap.square
..style = PaintingStyle.fill
..blendMode = BlendMode.multiply
..strokeWidth = 2;
for (int i = 0; i < points.length; i++) {
if (i + 1 == points.length) {
canvas.drawLine(points[i], points[0], paint);
} else {
canvas.drawLine(points[i], points[i + 1], paint);
}
canvas.drawCircle(points[i], 10, circlePaint);
}
}
}
@override
bool shouldRepaint(RectanglePainter oldPainter) => oldPainter.points != points || clear ;
}`
当前的样子:(您可以看到 Canvas 超出了范围。如果我记录手势检测器发出的坐标,即使在图片外部单击时,它们也高于 0。绿色边框显示它应该如何)
最佳答案
您可以使用 canvas.clipRect()
方法剪辑您的 Canvas
:
class RectanglePainter extends CustomPainter {
//...
RectanglePainter({@required this.points, @required this.clear, @required this.image});
@override
void paint(Canvas canvas, Size size) {
//...
canvas.clipRect(Rect.fromLTWH(0, 0, size.width, size.height));
}
}
关于flutter CustomPaint 和 GestureDetector 都调整到图像大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58613455/
我有一个绘制椭圆形的 CustomPaint。 我想在一个特定的位置切出一个洞,我还不知道它是如何工作的。 我试过: canvas.drawPath( Path.combine(PathO
我有一个简单的应用程序,它通过 CustomPainter 进行绘制 Canvas 上的红色或绿色圆圈,取决于在 AppBar 中按下了哪个按钮: 类(class)ColorCircle扩展 Cust
Column 的子 CustomPainter 的大小变为 (0, 0)。 1) 当我们刚刚使用 CustomPaint 和 CustomPainter 时,我们期望的大小被传递给 CustomPai
我正在渲染一组图 block 网格,其中每个图 block 都是从图像中提取的。为了渲染它,我在我自己的 CustomPainter 实现中渲染所有内容(因为网格可能会变得非常大)。为了支持平移和缩放
我有一个使用自定义涂料绘画的应用程序,我想在背景中添加一个图像,以便可以在其上绘画,但不幸的是我似乎无法弄清楚如何做到这一点,我尝试使用堆栈但每次我做的自定义油漆只会在容器上油漆,但出于某种原因永远不
我试图使用 alpha channel 通过 CustomPaint 对线条颜色应用透明度的Canvas.drawLine() . 问题 但是,alpha channel 上的颜色调整对结果没有影响,
介绍 我使用 Flutter 的 CustomPaint Widget 绘制了一个自定义标签栏,它看起来像这样: 此外,这是我用来绘制小部件的代码: class TabBarPainter exten
我想在页面的右下角画一个三角形。 我已经成功地在左上角创建了一个这样做: void paint(Canvas canvas, Size size) { // top left
我不能让自定义画家重新粉刷。 我尝试使用 Listenable、回调、setState 并没有重绘屏幕。 文档是这样说的: The most efficient way to trigger a re
我正在尝试在 custompainter 上绘制图像。我正在使用 flutter custompainter video 上的示例这是我到目前为止所拥有的。我可以在图像中绘制,但无法缩放图像。如何在手
我需要使用自定义画家在 ListTile 内呈现我的自定义对象,以便绘制一些自定义文本。 ListTile( title: CustomPaint( painter: RowPainter
我想知道是否有人对如何开始使用 CustomPainter 在 flutter 中绘制心形有任何指示。我已经设法画了三角形和正方形,或者一个基本的圆,但心当然有直线和曲线。 我有这个画一个三角形,看起
这就是我想要构建的: (只看 appBar 的形状而不是内容) 这是我的: 我希望边缘是弯曲的,而不是那么尖锐。 这是我的 CustomPaint 代码: class LogoPainter exte
我有以下小部件: class OutsiderButton extends StatelessWidget { final Function onPressed; final Icon ico
我实现了一个 CustomPainter。在 shouldRepaint 方法中,我必须比较 6 组深度相等性。我现在正在使用 setsEqual 来做这件事。如果它们非常相等,则无需重新绘制,但真的
我正在尝试在 CustomPainter 中创建一个动画,其中动画从底部开始向上,但它是从顶部开始的。 当点击 FloatActionButton 时,矩形应该上升到屏幕的最大高度,当再次点击时返回到
这个问题在这里已经有了答案: How to touch paint a canvas? (2 个答案) 关闭 4 年前。 我有一个大小为 300、300 的 CustomPaoint。在这个下方我还
因此,我正在尝试按照“签名 Canvas ”方法使用 Flutter 创建一个绘图应用程序。但是,我无法更改 CustomPaint 对象的颜色,而它在更改之前已经更改了每条线条绘制的颜色,如下所示:
我正在尝试在 Flutter 中的相机预览上显示 CustomPaint 元素。现在,CustomPaint 元素显示在相机预览下方。我正在使用 Flutter camera plugin显示相机预览
我正在尝试创建一个简单的小部件,以便当用户按下屏幕时,该位置会出现一个圆圈。我有一个由 Listener 小部件包装的 CustomPaint 小部件,如下所示: new
我是一名优秀的程序员,十分优秀!