Flutter安全保存图片插件gallery_saver_safety的使用
Flutter安全保存图片插件gallery_saver_safety的使用
说明
本插件是 gallery_saver
插件的一个副本,已迁移到 Null Safety。
使用说明
gallery_saver_safety
插件用于将网络或临时文件中的图片和视频保存到外部存储。保存后的图片和视频将在Android Gallery和iOS Photos中可见。
注意:如果你想要保存网络图片或视频链接,则该链接必须包含 http
或 https
前缀。
安装
首先,在你的 pubspec.yaml
文件中添加 gallery_saver_safety
作为依赖项。
iOS
在 Info.plist
文件中添加以下键:
<key>NSPhotoLibraryUsageDescription</key>
<string>描述为什么应用需要访问照片库的权限。</string>
Android
在 AndroidManifest.xml
文件中添加以下权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
示例代码
以下是完整的示例代码,展示了如何使用 gallery_saver_safety
插件来保存图片和视频。
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:gallery_saver_safety/gallery_saver_safety.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart';
double textSize = 20;
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
[@override](/user/override)
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String firstButtonText = '拍摄照片';
String secondButtonText = '录制视频';
String screenshotButtonText = '保存截图';
String albumName = '媒体';
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: Container(
color: Colors.white,
child: Column(
children: <Widget>[
Flexible(
flex: 1,
child: Container(
child: SizedBox.expand(
child: RaisedButton(
color: Colors.blue,
onPressed: _takePhoto,
child: Text(firstButtonText,
style: TextStyle(
fontSize: textSize, color: Colors.white)),
),
),
),
),
ScreenshotWidget(),
Flexible(
child: Container(
child: SizedBox.expand(
child: RaisedButton(
color: Colors.white,
onPressed: _recordVideo,
child: Text(secondButtonText,
style: TextStyle(
fontSize: textSize, color: Colors.blueGrey)),
),
)),
flex: 1,
)
],
),
),
),
));
}
void _takePhoto() async {
ImagePicker.platform.pickImage(source: ImageSource.camera)
.then((PickedFile recordedImage) {
if (recordedImage != null && recordedImage.path != null) {
setState(() {
firstButtonText = '保存中...';
});
GallerySaver.saveImage(recordedImage.path, albumName: albumName)
.then((bool success) {
setState(() {
firstButtonText = '照片已保存!';
});
});
}
});
}
void _recordVideo() async {
ImagePicker.platform.pickVideo(source: ImageSource.camera)
.then((PickedFile recordedVideo) {
if (recordedImage != null && recordedImage.path != null) {
setState(() {
secondButtonText = '保存中...';
});
GallerySaver.saveVideo(recordedVideo.path, albumName: albumName)
.then((bool success) {
setState(() {
secondButtonText = '视频已保存!';
});
});
}
});
}
void _saveNetworkVideo() async {
String path = 'https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4';
GallerySaver.saveVideo(path, albumName: albumName).then((bool success) {
setState(() {
print('视频已保存');
});
});
}
void _saveNetworkImage() async {
String path = 'https://image.shutterstock.com/image-photo/montreal-canada-july-11-2019-600w-1450023539.jpg';
GallerySaver.saveImage(path, albumName: albumName).then((bool success) {
setState(() {
print('图片已保存');
});
});
}
}
class ScreenshotWidget extends StatefulWidget {
[@override](/user/override)
_ScreenshotWidgetState createState() => _ScreenshotWidgetState();
}
class _ScreenshotWidgetState extends State<ScreenshotWidget> {
final GlobalKey _globalKey = GlobalKey();
[@override](/user/override)
Widget build(BuildContext context) {
return Flexible(
flex: 1,
child: RepaintBoundary(
key: _globalKey,
child: Container(
child: SizedBox.expand(
child: RaisedButton(
color: Colors.pink,
onPressed: _saveScreenshot,
child: Text(screenshotButtonText,
style: TextStyle(fontSize: textSize, color: Colors.white)),
),
),
),
),
);
}
Future<void> _saveScreenshot() async {
setState(() {
screenshotButtonText = '保存中...';
});
try {
// 提取字节
final RenderRepaintBoundary boundary = _globalKey.currentContext.findRenderObject();
final ui.Image image = await boundary.toImage(pixelRatio: 3.0);
final ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
final Uint8List pngBytes = byteData.buffer.asUint8List();
// 创建文件
final String dir = (await getApplicationDocumentsDirectory()).path;
final String fullPath = '$dir/${DateTime.now().millisecond}.png';
File capturedFile = File(fullPath);
await capturedFile.writeAsBytes(pngBytes);
print(capturedFile.path);
await GallerySaver.saveImage(capturedFile.path)
.then((value) {
setState(() {
screenshotButtonText = '截图已保存!';
});
});
} catch (e) {
print(e);
}
}
}
更多关于Flutter安全保存图片插件gallery_saver_safety的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter安全保存图片插件gallery_saver_safety的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用gallery_saver_safety
插件来安全保存图片的示例代码。这个插件提供了安全地将图片保存到设备图库的功能。
首先,确保你已经在pubspec.yaml
文件中添加了gallery_saver_safety
依赖:
dependencies:
flutter:
sdk: flutter
gallery_saver_safety: ^x.y.z # 请替换为最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,你可以按照以下步骤在你的Flutter应用中实现图片保存功能。
1. 导入插件
在你的Dart文件中导入gallery_saver_safety
插件:
import 'package:gallery_saver_safety/gallery_saver_safety.dart';
import 'dart:typed_data';
import 'dart:ui' as ui;
2. 获取图片数据
通常,你可能会从网络或本地图像资源中获取图片数据。以下是从网络获取图片数据并将其转换为Uint8List
的示例:
import 'dart:convert';
import 'package:http/http.dart' as http;
Future<Uint8List> fetchImageData(String imageUrl) async {
final response = await http.get(Uri.parse(imageUrl));
if (response.statusCode == 200) {
return Uint8List.fromList(response.bodyBytes);
} else {
throw Exception('Failed to load image');
}
}
3. 将图片保存到图库
使用GallerySaverSafety.saveImage
方法将图片保存到设备图库:
void saveImageToGallery(Uint8List imageData) async {
final result = await GallerySaverSafety.saveImage(
imageData,
quality: 100, // 图片质量,范围从0到100
name: 'saved_image.jpg', // 保存的图片名称
);
if (result!.isSuccess) {
print('Image saved successfully');
} else {
print('Failed to save image: ${result.msg}');
}
}
4. 完整示例
以下是一个完整的示例,展示了如何从网络获取图片并将其保存到设备图库:
import 'package:flutter/material.dart';
import 'package:gallery_saver_safety/gallery_saver_safety.dart';
import 'dart:typed_data';
import 'dart:convert';
import 'package:http/http.dart' as http;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Gallery Saver Safety Example'),
),
body: Center(
child: ElevatedButton(
onPressed: () async {
String imageUrl = 'https://example.com/path/to/your/image.jpg'; // 替换为实际的图片URL
Uint8List imageData = await fetchImageData(imageUrl);
await saveImageToGallery(imageData);
},
child: Text('Save Image'),
),
),
),
);
}
}
Future<Uint8List> fetchImageData(String imageUrl) async {
final response = await http.get(Uri.parse(imageUrl));
if (response.statusCode == 200) {
return Uint8List.fromList(response.bodyBytes);
} else {
throw Exception('Failed to load image');
}
}
void saveImageToGallery(Uint8List imageData) async {
final result = await GallerySaverSafety.saveImage(
imageData,
quality: 100,
name: 'saved_image.jpg',
);
if (result!.isSuccess) {
print('Image saved successfully');
} else {
print('Failed to save image: ${result.msg}');
}
}
确保在Android和iOS项目中配置了必要的权限,以便应用能够访问设备图库。在Android中,你可能需要在AndroidManifest.xml
中添加WRITE_EXTERNAL_STORAGE权限,并在运行时请求该权限。在iOS中,你需要在Info.plist
中添加NSPhotoLibraryAddUsageDescription权限说明。
这样,你就可以使用gallery_saver_safety
插件在Flutter应用中安全地保存图片了。