flutter保存图片到相册封装工具类

dart 复制代码
/// 使用 File api
import 'dart:io';

/// 使用 Uint8List 数据类型
import 'dart:typed_data';

/// 图片缓存管理
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/services.dart';

/// 使用 DefaultCacheManager 类(可能无法自动引入,需要手动引入)
import 'package:flutter_cache_manager/flutter_cache_manager.dart';

/// 保存文件或图片到本地
import 'package:image_gallery_saver/image_gallery_saver.dart';

/// 授权管理
import 'package:permission_handler/permission_handler.dart';

class ImageUtil {
  /// 保存图片到相册
  ///
  /// 默认为下载网络图片,如需下载资源图片,需要指定 [isAsset] 为 `true`。
  static Future<bool> saveImage(String imageUrl, {bool isAsset: false}) async {
    try {
      if (imageUrl == null) throw '保存失败,图片不存在!';

      /// 权限检测
      PermissionStatus storageStatus = await Permission.storage.status;
      if (storageStatus != PermissionStatus.granted) {
        storageStatus = await Permission.storage.request();
        if (storageStatus != PermissionStatus.granted) {
          throw '无法存储图片,请先授权!';
        }
      }

      /// 保存的图片数据
      Uint8List imageBytes;

      if (isAsset == true) {
        /// 保存资源图片
        ByteData bytes = await rootBundle.load(imageUrl);
        imageBytes = bytes.buffer.asUint8List();
      } else {
        /// 保存网络图片
        CachedNetworkImage image = CachedNetworkImage(imageUrl: imageUrl);
        DefaultCacheManager manager =
            image.cacheManager ?? DefaultCacheManager();
        Map<String, String> headers = image.httpHeaders;
        File file = await manager.getSingleFile(
          image.imageUrl,
          headers: headers,
        );
        imageBytes = await file.readAsBytes();
      }

      /// 保存图片
      final result = await ImageGallerySaver.saveImage(imageBytes);

      if (result == null || result == '') throw '图片保存失败';
      return true;
    } catch (e) {
      return false;
    }
  }

  /// 获取阿里云上图片缩略图
  static getOssImageThumbUrl(String url,
      {double width = 350.0, double height, int quality = 80}) {
    if (url.contains('?Size=') || url.contains('?size=')) {
      List<String> strList =
          url.contains('?Size=') ? url.split('?Size=') : url.split('?size=');
      url = strList.first;

      if (height == null) {
        String sizeStr = strList.last;
        List<String> sizeList = sizeStr.split('x');
        double oldImgWid = double.parse(sizeList.first);
        double oldImgHei = double.parse(sizeList.last);
        double newImgWid = width;
        double proportion = oldImgHei / oldImgWid;
        if (proportion > 1) {
          proportion = 4 / 3;
        } else {
          proportion = 3 / 4;
        }
        double newImgHei = proportion * newImgWid;
        url +=
            '?x-oss-process=image/resize,m_fill,w_${newImgWid.floor()},h_${newImgHei.floor()}/quality,q_$quality';
      } else {
        url +=
            '?x-oss-process=image/resize,m_fill,w_${width.floor()},h_${height.floor()}/quality,q_$quality';
      }
    } else {
      if (height != null) {
        url +=
            '?x-oss-process=image/resize,m_fill,w_${width.floor()},h_${height.floor()}/quality,q_$quality';
      }
    }

    return url;
  }
}
相关推荐
ujainu4 小时前
Flutter + OpenHarmony 游戏开发进阶:游戏主循环——AnimationController 实现 60fps 稳定帧率
flutter·游戏·openharmony
2601_949868364 小时前
Flutter for OpenHarmony 剧本杀组队App实战04:发起组队表单实现
开发语言·javascript·flutter
kirk_wang4 小时前
Flutter艺术探索-Flutter在鸿蒙端运行原理:OpenHarmony平台集成
flutter·移动开发·flutter教程·移动开发教程
晚霞的不甘4 小时前
Flutter for OpenHarmony专注与习惯的完美融合: 打造你的高效生活助手
前端·数据库·经验分享·flutter·前端框架·生活
2401_865854884 小时前
Uniapp和Flutter哪个更适合企业级开发?
flutter·uni-app
向哆哆5 小时前
Flutter × OpenHarmony 跨端实战:打造健身俱乐部「数据可视化仪表盘」模块
flutter·信息可视化·开源·鸿蒙·openharmony·开源鸿蒙
灰灰勇闯IT5 小时前
Flutter for OpenHarmony:卡片式 UI(Card Widget)设计 —— 构建清晰、优雅的信息容器
flutter·交互
灰灰勇闯IT5 小时前
Flutter for OpenHarmony:响应式布局(LayoutBuilder / MediaQuery)—— 构建真正自适应的鸿蒙应用
flutter·华为·harmonyos
晚霞的不甘5 小时前
Flutter for OpenHarmony手势涂鸦画板开发详解
前端·学习·flutter·前端框架·交互
晚霞的不甘5 小时前
Flutter for OpenHarmony 实现动态天气与空气质量仪表盘:从 UI 到动画的完整解析
前端·flutter·ui·前端框架·交互