How draw a rectangle directly on an image in flutter - flutter

I want to draw a rectangle on the actual image and don't want to use the flutter renderer to add a rectangle on the top layer just as a view. I can get the pixel color, but how can I overwrite the bonch of pixels?
ByteData byteData = await rootBundle.load('assets/images/maps/map.jpg');
Uint8List bytes = byteData.buffer.asUint8List();
List<int> values = bytes;
img.Image photo = img.decodeImage(values)!;
final pixels = photo.getBytes(format: img.Format.rgba);

I´m not quite sure, if this is the answer you need, but what about using a Stack?
Stack(children: [
image,
Positioned.fill(
child: CustomPaint(
painter: Sky(r),
child: Container()));
}),
],
)
...
class Sky extends CustomPainter {
Rect rect;
Sky(this.rect);
#override
void paint(Canvas canvas, Size size) {
canvas.drawRect(rect, Paint()..color = Colors.black);
}
#override
bool shouldRepaint(Sky oldDelegate) => false;
}

Related

How to apply different frames on image border in flutter

I search a lot how to apply frame on images but found no answer. I read stack function in which we can put an image inside other but its not good trick. I think there must be library for frame and by using that frame can automatically apply on border of image. Please guide me how can I use different design of frame outside image like some filters application.
I want to give options of frame to user like below and when user click on any frame that will apply on image
There are many approaches for that issue. I've used several in the past. It strongly differs in the way you want to make use of the image. Do you need to paint something on the image or just display it?
In my opinion multiple frames on an image can be achieved best with CustomPainter. Check out the documentation for more. The following Painter should do the trick.
class TestPainter extends CustomPainter {
final ui.Image image;
TestPainter({required this.image});
#override
void paint(Canvas canvas, Size size) {
//draw the image
canvas.drawImage(image, const Offset(0, 0), Paint());
double rectWidth = image.width.toDouble();
double rectHeight = image.height.toDouble();
final imageCenter = Offset(image.width / 2, image.height / 2);
//first frame
var border1 = Rect.fromCenter(
center: imageCenter,
width: rectWidth + 1,
height: rectHeight + 1);
var painting = Paint();
painting.color = Colors.red;
painting.strokeWidth = 2;
painting.style = PaintingStyle.stroke;
canvas.drawRect(border1, painting);
//second frame
var border2 = Rect.fromCenter(
center: imageCenter,
width: rectWidth + 3,
height: rectHeight + 3);
var painting2 = Paint();
painting2.color = Colors.green;
painting2.strokeWidth = 2;
painting2.style = PaintingStyle.stroke;
canvas.drawRect(
border2,
painting2,
);
}
#override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
Please be cautious. The Image in that example needs to be an Image of the dart:ui library (Documentation). There are various way to convert. Depends on your project.

Flutter Custom Shape

I need to make a shape as seen in the photo below with container in Flutter, can you help me for this?
use this code to create shape like this
import 'dart:ui' as ui;
//Add this CustomPaint widget to the Widget Tree
CustomPaint(
size: Size(WIDTH, (WIDTH*0.3542581280172481).toDouble()), //You can Replace [WIDTH] with your desired width for Custom Paint and height will be calculated automatically
painter: RPSCustomPainter(),
)
//Copy this CustomPainter code to the Bottom of the File
class RPSCustomPainter extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
Path path_0 = Path();
path_0.moveTo(size.width*1.156952,size.height*3.936736);
path_0.lineTo(size.width*1.968605,size.height*3.949394);
path_0.cubicTo(size.width*1.968605,size.height*3.949394,size.width*2.151398,size.height*4.204300,size.width*2.152460,size.height*4.443043);
path_0.cubicTo(size.width*2.153491,size.height*4.675744,size.width*1.977573,size.height*4.936736,size.width*1.977573,size.height*4.936736);
path_0.lineTo(size.width*1.152468,size.height*4.898765);
path_0.lineTo(size.width*1.156952,size.height*3.936736);
path_0.close();
Paint paint_0_fill = Paint()..style=PaintingStyle.fill;
paint_0_fill.color = Color.fromRGBO(216, 216, 216,1.0).withOpacity(1.0);
canvas.drawPath(path_0,paint_0_fill);
}
#override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}

Flutter Create circle with multiple sections with touch gesture

I want to create widget using custom painter like following with touch gesture;
Draw svg of this image. Then convert into flutter paint code using
https://fluttershapemaker.com/
Add the touchable package as dependency in your pubspec.yaml
https://github.com/nateshmbhat/touchable
Example :
CanvasTouchDetector(
builder: (context) =>
CustomPaint(
painter: MyPainter(context)
)
)
class MyPainter extends CustomPainter {
final BuildContext context ;
MyPainter(this.context); // context from CanvasTouchDetector
#override
void paint(Canvas canvas, Size size) {
var myCanvas = TouchyCanvas(context,canvas);
myCanvas.drawCircle(Offset(10, 10), 60, Paint()..color=Colors.orange ,
onTapDown: (tapdetail) {
print("orange Circle touched");
},
onPanDown:(tapdetail){
print("orange circle swiped");
}
);
myCanvas.drawLine(
Offset(0, 0),
Offset(size.width - 100, size.height - 100),
Paint()
..color = Colors.black
..strokeWidth = 50,
onPanUpdate: (detail) {
print('Black line Swiped'); //do cooler things here. Probably change app state or animate
});
}
}

How to draw custom shape in flutter and drag that shape around?

At the moment I can draw rectangles using CustomPainter. Below the code inside the paint method of my CustomPainter.
for (var rectPoints in rectangles) {
paint.color = rectPoints.color;
paint.strokeWidth = rectPoints.strokeWidth;
if (rectPoints.selected != null && rectPoints.selected == true) {
paint.color = Colors.black45;
}
var rect = Rect.fromLTWH(
rectPoints.startPoint.dx,
rectPoints.startPoint.dy,
rectPoints.endPoint.dx - rectPoints.startPoint.dx,
rectPoints.endPoint.dy - rectPoints.startPoint.dy);
canvas.drawRect(rect, paint);
}
var rect = Rect.fromLTWH(startPoint.dx, startPoint.dy,
endPoint.dx - startPoint.dx, endPoint.dy - startPoint.dy);
canvas.drawRect(rect, paint);
A rectangle is a custom object with startPoint, endPoint and some other properties needed to draw that specific rectangle. Now I want to select a rectangle and re-position it. Any help would be appreciated. Thanks
You'll need to track the state of the rectangles' positions independent of the canvas drawing. The easiest way to do that is to use a StatefulWidget. You'll also need to use a GestureDetector to capture the pan events. Then you can wire up the gesture details to the position of the rectangles and call the painter to redraw everything.
Here's a simple app that shows how to do it with one rectangle. Should be straightforward to expand it to handle multiple ones.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Draggable Custom Painter',
home: Scaffold(
body: CustomPainterDraggable(),
),
);
}
}
class CustomPainterDraggable extends StatefulWidget {
#override
_CustomPainterDraggableState createState() => _CustomPainterDraggableState();
}
class _CustomPainterDraggableState extends State<CustomPainterDraggable> {
var xPos = 0.0;
var yPos = 0.0;
final width = 100.0;
final height = 100.0;
bool _dragging = false;
/// Is the point (x, y) inside the rect?
bool _insideRect(double x, double y) =>
x >= xPos && x <= xPos + width && y >= yPos && y <= yPos + height;
#override
Widget build(BuildContext context) {
return GestureDetector(
onPanStart: (details) => _dragging = _insideRect(
details.globalPosition.dx,
details.globalPosition.dy,
),
onPanEnd: (details) {
_dragging = false;
},
onPanUpdate: (details) {
if (_dragging) {
setState(() {
xPos += details.delta.dx;
yPos += details.delta.dy;
});
}
},
child: Container(
color: Colors.white,
child: CustomPaint(
painter: RectanglePainter(Rect.fromLTWH(xPos, yPos, width, height)),
child: Container(),
),
),
);
}
}
class RectanglePainter extends CustomPainter {
RectanglePainter(this.rect);
final Rect rect;
#override
void paint(Canvas canvas, Size size) {
canvas.drawRect(rect, Paint());
}
#override
bool shouldRepaint(CustomPainter oldDelegate) => true;
}
I have developed a library called
touchable for the purpose of adding gesture callbacks to each individual shape you draw on the canvas. You can draw your shapes and add onPanUpdate or onTapDown callbacks to drag your shape around.
Here's what you can do to detect touch and drag on your circle.
Here's a small example taken directly from the pub dev site :
Wrap your CustomPaint widget with CanvasTouchDetector. It takes a builder function as argument that expects your CustomPaint widget as shown below.
import 'package:touchable/touchable.dart';
CanvasTouchDetector(
builder: (context) =>
CustomPaint(
painter: MyPainter(context)
)
)
Inside your CustomPainter class's paint method , create and use the TouchyCanvas object (using the context obtained from the CanvasTouchDetector and canvas) to draw your shape and you can give gesture callbacks like onPanUpdate , onTapDown here to detect your drag events.
var myCanvas = TouchyCanvas(context,canvas);
myCanvas.drawRect( rect , Paint() , onPanUpdate: (detail){
//This callback runs when you drag this rectangle. Details of the location can be got from the detail object.
//Do stuff here. Probably change your state and animate
});

Creating image masks in flutter

Flutter provides several ways for masks based on paths i.e. clip paths. I am trying to figure out a way where one could take an image with transparency layer like example below and use that image to mask another image / view or as a general mask.
My first instinct was to look at CustomPaint class, but I can't figure it out past this initial idea.
Flutter has BoxDecoration class that takes in BlendMode enum. By utilising these you can achieve various mask effects using images, for my particular case above dstIn was a solution.
I have posted an answer to my own same problem here, using a custom painter class with a squircle mask and image.
#override
void paint(Canvas canvas, Size size) {
if (image != null && mask != null) {
var rect = Rect.fromLTRB(0, 0, 200, 200);
Size outputSize = rect.size;
Paint paint = new Paint();
//Mask
Size maskInputSize = Size(mask.width.toDouble(), mask.height.toDouble());
final FittedSizes maskFittedSizes =
applyBoxFit(BoxFit.cover, maskInputSize, outputSize);
final Size maskSourceSize = maskFittedSizes.source;
final Rect maskSourceRect = Alignment.center
.inscribe(maskSourceSize, Offset.zero & maskInputSize);
canvas.saveLayer(rect, paint);
canvas.drawImageRect(mask, maskSourceRect, rect, paint);
//Image
Size inputSize = Size(image.width.toDouble(), image.height.toDouble());
final FittedSizes fittedSizes =
applyBoxFit(BoxFit.cover, inputSize, outputSize);
final Size sourceSize = fittedSizes.source;
final Rect sourceRect =
Alignment.center.inscribe(sourceSize, Offset.zero & inputSize);
canvas.drawImageRect(
image, sourceRect, rect, paint..blendMode = BlendMode.srcIn);
canvas.restore();
}
}
Result: