gpt4 book ai didi

flutter - 如何在 Flutter 中截取 CameraPreview 的屏幕截图?

转载 作者:IT王子 更新时间:2023-10-29 07:00:47 66 4
gpt4 key购买 nike

我需要快速访问我的新 Flutter 应用的 CameraPreview 数据。如果我使用 controller.takePicture(filePath) 拍照,文件需要几秒钟的时间才能保存到磁盘,以便我可以访问它。我不需要高质量的图像,因此获得与手机屏幕显示分辨率相同的分辨率就可以了。我试过this method ,但它只捕获我自己绘制的叠加层和小部件,而不是相机预览数据。这是使用 this method 时问题的最小工作示例:

https://www.youtube.com/watch?v=CWBLjCwH5c0

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:async';
import 'package:camera/camera.dart';
import 'dart:ui' as ui;

List<CameraDescription> cameras;

Future<Null> main() async {
debugPaintSizeEnabled = false;
debugPaintLayerBordersEnabled = false;
try {
cameras = await availableCameras();
} on CameraException catch (e) {
logError(e.code, e.description);
}

runApp(new MaterialApp(
home: new MyApp(),
));
}

void logError(String code, String message) =>
print('Error: $code\nError Message: $message');

class MyApp extends StatefulWidget {
@override
_State createState() => new _State();
}

class _State extends State<MyApp> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
static GlobalKey previewContainer = new GlobalKey();
CameraController controller;
ui.Image image;
Offset blueSquareOffset = new Offset(10.0, 10.0);

@override
void initState() {
super.initState();

controller = new CameraController(cameras[0], ResolutionPreset.low);
controller.initialize().then((_) {
if (!mounted) {
return;
}
setState(() {});
});
}

@override
void dispose() {
controller?.dispose();
super.dispose();
}

void _getScreenShotImage() async {
_capturePng();
image = await _capturePng();
debugPrint("im height: ${image.height}, im width: ${image.width}");
setState(() {});
}

Future<ui.Image> _capturePng() async {
RenderRepaintBoundary boundary =
previewContainer.currentContext.findRenderObject();
ui.Image image = await boundary.toImage();
return image;
}

/// Display the preview from the camera (or a message if the preview is not available).
Widget _cameraPreviewWidget() {
if (controller == null || !controller.value.isInitialized) {
return const Text('Camera is initialising...');
} else {
return Center(
child: new AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: RepaintBoundary(
//key: previewContainer,
child: new GestureDetector(
child: new CameraPreview(controller),
),
)),
);
}
}

void _moveBlueSquare(DragUpdateDetails details) {
setState(() {
_getScreenShotImage();
blueSquareOffset = blueSquareOffset + details.delta;
});
}

Widget _blueSquare() {
return new Positioned(
top: blueSquareOffset.dy,
left: blueSquareOffset.dx,
width: 50.0,
height: 50.0,
child: new GestureDetector(
onPanUpdate: _moveBlueSquare,
child: new Container(
color: Color.fromARGB(255, 10, 10, 255),
)));
}

@override
Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldKey,
appBar: new AppBar(
title: new Text('Render Boundry Screenshot Error Example'),
),
body: RepaintBoundary(
key: previewContainer,
child: new Container(
padding: new EdgeInsets.all(0.0),
margin: new EdgeInsets.all(0.0),
child: new RepaintBoundary(
//key: previewContainer,
child: new Stack(
fit: StackFit.expand,
overflow: Overflow.clip,
children: <Widget>[
new Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new Expanded(
child: new Stack(children: <Widget>[
new RepaintBoundary(
child: new Container(child: _cameraPreviewWidget()),
),
_blueSquare(),
])),
new Expanded(
child: new Container(
//color: Color.fromARGB(50, 50, 50, 50),
child: new CustomPaint(
painter: new RectanglePainter(image),
)),
)
],
),
],
)))));
}
}

class RectanglePainter extends CustomPainter {
RectanglePainter(this.image);

ui.Image image;

@override
void paint(Canvas canvas, Size size) {
if (image == null) {
canvas.drawRect(
new Rect.fromLTRB(100.0, 50.0, 300.0, 200.0),
new Paint()
..color = Color.fromARGB(255, 50, 50, 255)
..style = PaintingStyle.stroke
..strokeWidth = 6.0);
} else {
canvas.drawImage(image, new Offset(0.0, 0.0), new Paint());
}
}

@override
bool shouldRepaint(RectanglePainter old) {
return true;
}
}

如有任何帮助,我们将不胜感激。

最佳答案

更新:2020 年 7 月

目前,在 Flutter 上获取 CameraPreview 屏幕截图的最佳方式是使用 native_screenshot包。

你可以简单地使用,

Future<void> getScreenshot() async{
String path = await NativeScreenshot.takeScreenshot();
print(path);
}

保存截图。有关其他权限和设置,请参阅包页面。在性能方面,它似乎有点慢(在我的 2018 小米 A1 上为 500ms-1s)。我目前正在寻找提高屏幕捕获速度的方法。

关于flutter - 如何在 Flutter 中截取 CameraPreview 的屏幕截图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51103815/

66 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com