ToB企服应用市场:ToB评测及商务社交产业平台
标题:
Flutter 学习之旅 之 flutter 在 Android 端举行简单的图片裁剪操作
[打印本页]
作者:
丝
时间:
昨天 20:14
标题:
Flutter 学习之旅 之 flutter 在 Android 端举行简单的图片裁剪操作
Flutter 学习之旅 之 flutter 在 Android 端举行简单的图片裁剪操作
目录
Flutter 学习之旅 之 flutter 在 Android 端举行简单的图片裁剪操作
一、简单介绍
二、简单介绍 image_cropper
三、安装 image_picker
四、简单案例实现
五、关键代码
一、简单介绍
Flutter 是一款开源的 UI 软件开发工具包,由 Google 开发和维护。它允许开发者使用一套代码同时构建跨平台的应用程序,包罗移动设备(iOS 和 Android)、Web 和桌面平台(Windows、macOS 和 Linux)。
Flutter 使用 Dart 编程语言,它可以将代码编译为 ARM 或 Intel 呆板代码以及 JavaScript,从而实现快速的性能。Flutter 提供了一个丰富的预置小部件库,开发者可以根据本身的需求机动地控制每个像素,从而创建自界说的、顺应性强的计划,这些计划在任何屏幕上都能出现出色的外观和感觉。
二、简单介绍 image_cropper
网址:image_cropper | Flutter package
image_cropper 是一个功能强大的 Flutter 插件,用于实现图片裁剪功能。它支持多种裁剪模式和自界说配置,适用于必要让用户在上传图片前举行裁剪的场景。
三、安装 image_picker
1、直接运行命令
使用 Flutter:flutter pub add image_cropper
用到:flutter pub add path_provider
2、或者在 pubspec.yaml 添加
dependencies:
image_cropper: ^9.0.0
path_provider: ^2.1.5
复制代码
四、简单案例实现
1、这里使用 Android Studio 举行创建 Flutter 项目
2、创建一个 application 的 Flutter 项目
3、工程创建后如下
4、在 lib/main.dart 编写代码实现图片显示,然后举行简单裁剪
5、添加图片
assets 也可以叫做资源。资源是与您的应用程序一起捆绑和摆设的文件,可在运行时访问。常见的资源类型包罗静态数据(例如 JSON 文件)、配置文件、图标和图像(JPEG、WebP、GIF、动画 WebP/GIF、PNG、BMP 和 WBMP)。
每个资源都由资源文件所在的显式路径(相对于 pubspec.yaml 文件)标识。声明资源的顺序无关紧要。包罗资源的目录名称无关紧要。
在构建过程中,Flutter 将资源放入一个名为资源包的特殊存档中,应用程序会在运行时从中读取。
Flutter 使用位于项目根目录的 pubspec.yaml 文件来识别应用程序所需的资源。
资源文件夹的名称是随意的,我们可以把资源文件夹放在和 lib 平级的根目录下面,为图片建立文件夹 images,把上面示例中的猫头鹰图片放入其中。
修改 pubspec.yaml 的配置
flutter:
assets:
- images/imagename.png
复制代码
在代码中可以通过 images/imagename.png 使用图片。
Image.asset(
'images/owl.png',
width: 200,
height: 200,
);
复制代码
当你发布应用程序的时候,pubspec.yaml 中配置的图片会和代码一起打包发布。
如果有很多图片,这样一张一张注册很是麻烦,我们可以直接指定文件夹。好比我们可以一次性注册 images 文件夹下面的所有图片。
flutter:
assets:
- images/
复制代码
6、这里用到 image_cropper,以是必要声明 UCropActivity
在 AndroidManifest.xml 中声明 UCropActivity,否则 image_cropper 插件可能无法正常工作:
<application
...>
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
</application>
复制代码
完整的参考如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:label="test_image_crop"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
</application>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
</queries>
</manifest>
复制代码
7、连接设备,运行项目,简单结果如下
五、关键代码
import 'dart:io'; // 导入 Dart 的文件操作库,用于文件读写
import 'package:flutter/material.dart'; // 导入 Flutter 的 Material 组件库
import 'package:image_cropper/image_cropper.dart'; // 导入 image_cropper 插件,用于裁剪图片
import 'package:path_provider/path_provider.dart'; // 导入 path_provider 插件,用于获取临时目录路径
import 'package:flutter/services.dart'; // 导入 Flutter 的服务库,用于加载资源文件
void main() {
runApp(MyApp()); // 启动应用
}
// 定义一个无状态的 MyApp 组件
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Image Cropper Demo', // 应用标题
theme: ThemeData(
primarySwatch: Colors.blue, // 设置主题颜色为蓝色
),
home: ImageCropperDemo(), // 设置首页为 ImageCropperDemo 页面
);
}
}
// 定义一个有状态的 ImageCropperDemo 组件
class ImageCropperDemo extends StatefulWidget {
@override
_ImageCropperDemoState createState() => _ImageCropperDemoState();
}
class _ImageCropperDemoState extends State<ImageCropperDemo> {
CroppedFile? _croppedFile; // 用于存储裁剪后的图片文件
final String _imageAssetPath = 'images/sunwukongd.jpg'; // 替换为你的图片路径
// 将资源文件复制到临时路径
Future<File> _copyAssetToTemp(String assetPath) async {
final tempDir = await getTemporaryDirectory(); // 获取设备的临时目录路径
final tempFilePath = '${tempDir.path}/temp_image.jpg'; // 定义临时文件路径
final ByteData data = await rootBundle.load(assetPath); // 从资源文件加载图片数据
final bytes = data.buffer.asUint8List(); // 将图片数据转换为字节列表
await File(tempFilePath).writeAsBytes(bytes); // 将字节数据写入临时文件
return File(tempFilePath); // 返回临时文件对象
}
// 裁剪图片的方法
Future<void> _cropImage() async {
try {
final tempFile = await _copyAssetToTemp(_imageAssetPath); // 将资源文件复制到临时路径
// 调用 ImageCropper 裁剪图片
final croppedFile = await ImageCropper().cropImage(
sourcePath: tempFile.path, // 指定裁剪的源图片路径
uiSettings: [
AndroidUiSettings( // 配置 Android 裁剪界面的样式
toolbarTitle: '裁剪图片', // 工具栏标题
toolbarColor: Colors.blue, // 工具栏背景颜色
toolbarWidgetColor: Colors.white, // 工具栏文字颜色
initAspectRatio: CropAspectRatioPreset.original, // 初始裁剪比例为原始图片比例
lockAspectRatio: false, // 不锁定裁剪比例,允许自由裁剪
),
IOSUiSettings( // 配置 iOS 裁剪界面的样式
title: '裁剪图片', // 裁剪界面标题
),
],
);
if (croppedFile != null) { // 如果裁剪成功
setState(() {
_croppedFile = croppedFile; // 更新裁剪后的图片文件
});
}
} catch (e) {
print('裁剪失败: $e'); // 如果裁剪失败,打印错误信息
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Image Cropper Demo'), // 设置应用栏标题
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center, // 垂直居中对齐
children: [
// 显示裁剪后的图片
if (_croppedFile != null) // 如果裁剪后的图片不为空
Image.file(
File(_croppedFile!.path), // 显示裁剪后的图片
width: 300, // 图片宽度
height: 300, // 图片高度
fit: BoxFit.contain, // 使用 BoxFit.contain 保持图片比例
)
else // 如果裁剪后的图片为空,显示原始图片
Image.asset(
_imageAssetPath, // 显示原始图片
width: 300, // 图片宽度
height: 300, // 图片高度
fit: BoxFit.contain, // 使用 BoxFit.contain 保持图片比例
),
SizedBox(height: 20), // 添加间距
ElevatedButton(
onPressed: _cropImage, // 点击按钮触发裁剪操作
child: Text('裁剪图片'), // 按钮文字
),
],
),
),
);
}
}
复制代码
代码说明
资源文件处置惩罚
:
使用 rootBundle.load 从资源文件加载图片数据,并将其写入临时文件。这是由于 image_cropper 插件必要一个当地文件路径,而不是资源文件路径。
裁剪功能
:
使用 image_cropper 插件的 cropImage 方法打开裁剪界面。
配置 AndroidUiSettings 和 IOSUiSettings,设置裁剪界面的样式。
设置 lockAspectRatio: false,允许用户自由选择裁剪区域。
显示图片
:
使用 Image.file 显示裁剪后的图片。
使用 Image.asset 显示原始图片。
使用 BoxFit.contain 确保图片在显示时保持原始比例,不会被拉伸。
错误处置惩罚
:
使用 try-catch 捕获裁剪过程中可能出现的错误,并打印错误信息。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4