拍照指定裁剪大小

秋天来了

今年的冬天会比往年冷吗

也许要看棉被的厚度

需求来了

(1)自定义拍照界面。预览相机,并在上面添加其他操作的组件。如切换相机,拍照按钮,手电筒。

(2)拍好照片后直接裁剪指定范围。拍照的时候获取到照片为指定尺寸的全屏照片,如480p或720p或1080p。拍好照片后,上传到服务器为了减少识别压力,则裁剪照片获取中间部分。

实现的效果

省流-> 编写的DEMO地址

一、自定义拍照

1. 集成

官网提供了使用教程使用 Camera 插件实现拍照功能,按完整样例可以实现。

方便在页面中使用,则将

java 复制代码
void _initializeCamera() async {
    // Ensure that plugin services are initialized so that `availableCameras()`
    // can be called before `runApp()`
    WidgetsFlutterBinding.ensureInitialized();
​
    // Obtain a list of the available cameras on the device.
    final cameras = await availableCameras();
​
    // Get a specific camera from the list of available cameras.
    firstCamera = cameras.first;
​
    // To display the current output from the Camera,
    // create a CameraController.
    _controller = CameraController(
        // Get a specific camera from the list of available cameras.
        cameras.first,
        // Define the resolution to use.
        ResolutionPreset.high,
        enableAudio: false,
        imageFormatGroup: ImageFormatGroup.jpeg);
​
    // Next, initialize the controller. This returns a Future.
    _initializeControllerFuture = _controller.initialize();
​
    _valueNotifier.value = true;
  }

放到initState中进行初始化。

2. 提速

另一个需要注意点:final image = await _controller.takePicture();执行时间在3-4秒的处理时间,比常规的拍照慢了好多。

多次测试和验证后,确认原因为: "对焦"

解决方法:在拍照前,锁定聚焦。

csharp 复制代码
      // 设置对焦,提高拍照效率
      await _controller.setFocusMode(FocusMode.locked);
      await _controller.setExposureMode(ExposureMode.locked);

二、裁剪

自定义拍照后返回一个XFile可获取照片保存的路径。在上传之前,不需要用户手动裁剪,直接截取照片的指定位置(demo中为获取中间部分)。

1. 文件转ui.Image类型

读取文件转为ui.Image如下:

scss 复制代码
//通过 文件读取Image
  static Future<ui.Image> loadImageByFile(String path) async {
    var list = await File(path).readAsBytes();
    return loadImageByUint8List(list);
  }
​
  //通过[Uint8List]获取图片
  static Future<ui.Image> loadImageByUint8List(Uint8List list) async {
    ui.Codec codec = await ui.instantiateImageCodec(list);
    ui.FrameInfo frame = await codec.getNextFrame();
    return frame.image;
  }
2. 裁剪

获取到ui.Image后,使用PictureRecorder后将图片绘制需要的部分,并保存为ui.Image

ini 复制代码
double width = background.width.toDouble();
    double height = background.height.toDouble();
    PictureRecorder recorder = PictureRecorder();
    Canvas canvas = Canvas(recorder);
    Rect rect = Rect.fromLTWH(0, height / 3, width, height / 3);
    Rect dstRect = Rect.fromLTWH(0, 0, width, height / 3);
    canvas.drawImageRect(background, rect, dstRect, Paint());
    Picture picture = recorder.endRecording();
    ui.Image image = await picture.toImage(width.toInt(), height ~/ 3);
3. 保存到临时文件

裁剪好图片后,写入到文件,或展示。

ini 复制代码
// 写入到文件夹中
    ByteData? byteData = await image.toByteData(format: ImageByteFormat.png);
    if (null != byteData) {
      try {
        final Directory appCache = await getApplicationCacheDirectory();
        var filePath = "${appCache.path}/test${DateTime.now().millisecondsSinceEpoch}.png";
        File file = File(filePath);
        file = await file.writeAsBytes(byteData.buffer.asUint8List());
​
        setState(() {
          _croppedImagePath = file.path;
        });
      } on MissingPlatformDirectoryException catch (e) {
        debugPrint("保存图片失败,${e.message}");
      }
    }

保存到data/data/包名/cache/的目录下,可以自行切换。

三、 完成

搜索了很久没有找到flutter来实现裁剪图片的,有一个库image_cropper,主要还是需要用户参与,然后移动框进行裁剪,不是很符合我们的要求。

参考了Flutter 绘制番外 | 将你的 Canvas 绘制保存为图片提供的方法。此方法太好用了,不知道还真想不到。

相关推荐
LawrenceLan9 小时前
Flutter 零基础入门(九):构造函数、命名构造函数与 this 关键字
开发语言·flutter·dart
一豆羹10 小时前
macOS 环境下 ADB 无线调试连接失败、Protocol Fault 及端口占用的深度排查
flutter
行者9610 小时前
OpenHarmony上Flutter粒子效果组件的深度适配与实践
flutter·交互·harmonyos·鸿蒙
行者9612 小时前
Flutter与OpenHarmony深度集成:数据导出组件的实战优化与性能提升
flutter·harmonyos·鸿蒙
小雨下雨的雨12 小时前
Flutter 框架跨平台鸿蒙开发 —— Row & Column 布局之轴线控制艺术
flutter·华为·交互·harmonyos·鸿蒙系统
小雨下雨的雨13 小时前
Flutter 框架跨平台鸿蒙开发 —— Center 控件之完美居中之道
flutter·ui·华为·harmonyos·鸿蒙
小雨下雨的雨14 小时前
Flutter 框架跨平台鸿蒙开发 —— Icon 控件之图标交互美学
flutter·华为·交互·harmonyos·鸿蒙系统
小雨下雨的雨14 小时前
Flutter 框架跨平台鸿蒙开发 —— Placeholder 控件之布局雏形美学
flutter·ui·华为·harmonyos·鸿蒙系统
行者9614 小时前
OpenHarmony Flutter弹出菜单组件深度实践:从基础到高级的完整指南
flutter·harmonyos·鸿蒙
前端不太难15 小时前
Flutter / RN / iOS,在长期维护下的性能差异本质
flutter·ios