精选文章

Flutter 图片选择与裁剪

2024-09-28 · 组件

图片选择与裁剪通常需要统一封装,避免业务层重复实现。下面以 image_picker + crop_your_image 为例。

0. 依赖

dependencies:
  image_picker: ^0.8.5
  crop_your_image: ^0.7.5

0.1 平台配置(关键)

Android:AndroidManifest.xml 添加相机/相册权限。
iOS:Info.plist 添加 NSPhotoLibraryUsageDescriptionNSCameraUsageDescription

1. 选择图片

final picker = ImagePicker();

Future<XFile?> pickImage() async {
  return picker.pickImage(source: ImageSource.gallery);
}

1.1 相机拍照

await picker.pickImage(source: ImageSource.camera);

1.2 限制尺寸

await picker.pickImage(
  source: ImageSource.gallery,
  maxWidth: 1024,
  maxHeight: 1024,
);

2. 裁剪组件

class CropPage extends StatefulWidget {
  final Uint8List image;
  const CropPage({super.key, required this.image});

  @override
  State<CropPage> createState() => _CropPageState();
}

class _CropPageState extends State<CropPage> {
  final controller = CropController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(actions: [
        IconButton(
          icon: const Icon(Icons.check),
          onPressed: () => controller.crop(),
        )
      ]),
      body: Crop(
        controller: controller,
        image: widget.image,
        onCropped: (data) {
          Navigator.pop(context, data);
        },
      ),
    );
  }
}

3. 完整流程

final file = await pickImage();
if (file == null) return;
final bytes = await file.readAsBytes();
final cropped = await Navigator.push<Uint8List>(
  context,
  MaterialPageRoute(builder: (_) => CropPage(image: bytes)),
);

4. 常见坑点

  • 权限未配置:iOS/Android 会直接崩溃
  • 大图内存:建议限制尺寸或压缩

5. 实践清单

  • 选择图片统一入口
  • 裁剪页独立封装
  • 返回 Uint8List 供上传或保存

JJ

作者简介

专注于内容创作、产品策略与设计实践。欢迎交流合作。

上一篇 下一篇