写真を撮った際に指定の部分だけを塗り潰す機能がほしくて、色々パッケージを探したんですが見つけられなかったので試しに実装してみました。
CustomPaintではなく、塗り潰し色のContainerを座標配置するだけの単純な実装です。
ImageウィジェットにStackでContainerを重ねているだけなので、ここから画像化して取り出すにはもうひと工夫必要となりそうです。
進展あればまた書きます。
import 'package:flutter/material.dart';
class ImageMaskingController {
late _ImageMaskingState imageMaskingState;
void clear() {
imageMaskingState.clear();
}
}
@immutable
class ImageMasking extends StatefulWidget {
const ImageMasking({
Key? key,
required this.assetName,
required this.controller,
}) : super(key: key);
final String assetName;
final ImageMaskingController controller;
@override
_ImageMaskingState createState() => _ImageMaskingState();
}
class _ImageMaskingState extends State<ImageMasking> {
var _isDrag = false;
final _rects = <Rect>[];
var _startX = 0;
var _startY = 0;
@override
void initState() {
super.initState();
widget.controller.imageMaskingState = this;
}
@override
Widget build(BuildContext context) {
final widgets = <Widget>[
Image(
image: AssetImage(widget.assetName),
fit: BoxFit.contain,
),
];
for (final rect in _rects) {
widgets.add(
Positioned(
left: rect.left,
top: rect.top,
width: rect.width,
height: rect.height,
child: Container(
color: Colors.yellow,
),
),
);
}
return GestureDetector(
onPanDown: _onPanDown,
onPanStart: _onPanStart,
onPanUpdate: _onPanUpdate,
onPanEnd: _onPanEnd,
onPanCancel: _onPanCancel,
child: Container(
color: Colors.yellow,
child: Stack(
children: widgets,
),
),
);
}
void _onPanDown(DragDownDetails details) {}
void _onPanStart(DragStartDetails details) {
setState(() {
_isDrag = true;
_startX = details.localPosition.dx.toInt();
_startY = details.localPosition.dy.toInt();
_rects.add(Rect.fromLTWH(
_startX.toDouble(),
_startY.toDouble(),
0,
0,
));
});
}
void _onPanUpdate(DragUpdateDetails details) {
if (!_isDrag) {
return;
}
setState(() {
final endX = details.localPosition.dx.toInt();
final endY = details.localPosition.dy.toInt();
final rect = Rect.fromLTRB(
(_startX < endX ? _startX : endX).toDouble(),
(_startY < endY ? _startY : endY).toDouble(),
(_startX < endX ? endX : _startX).toDouble(),
(_startY < endY ? endY : _startY).toDouble(),
);
_rects
..removeLast()
..add(rect);
});
}
void _onPanEnd(DragEndDetails details) {
setState(() {
_isDrag = false;
_startX = _startY = 0;
final lastRect = _rects[_rects.length - 1];
if (lastRect.width <= 0 || lastRect.height <= 0) {
_rects.removeLast();
}
debugPrint(lastRect.toString());
});
}
void _onPanCancel() {}
void clear() {
setState(_rects.clear);
}
}
コメント
[…] Flutterで写真の特定部分を塗り潰す機能を試しに実装してみた写真を撮った… […]