图片拼图工具应用


欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net

适配的第三方库地址:

一、项目概述

运行效果图
image-20260412113450577
image-20260412113456378image-20260412113500987

image-20260412113504953image-20260412113509737

1.1 应用简介

图片拼图工具是一款创意十足的图片拼接应用,帮助用户将多张图片拼接成精美的拼图作品。应用提供11种拼图模板,支持2-9张图片的灵活组合,用户可自定义边框样式、圆角效果、拼图比例和背景颜色,打造独一无二的拼图效果。完成的拼图可一键保存到相册或分享到社交平台,让美好瞬间更加精彩。

应用以活力的粉色为主色调,象征创意与活力。涵盖创建、模板、历史、设置四大模块。用户可以轻松选择图片、挑选模板、调整样式、生成拼图,实现图片的创意组合。

1.2 核心功能

功能模块功能描述实现方式
图片选择从相册选择多张图片image_picker
模板选择11种拼图模板可选模板枚举
边框样式无边框、细、中、粗边框样式设置
圆角效果直角到圆形五种圆角样式设置
拼图比例正方形、4:3、16:9等比例设置
背景颜色多种背景色可选颜色选择
图片排序拖拽调整图片顺序ReorderableListView
保存相册将拼图保存到相册image_gallery_saver
分享功能分享拼图到社交平台share_plus

1.3 拼图模板定义

序号模板名称图片数行数列数描述
12宫格212横向排列2张
23宫格313横向排列3张
34宫格422经典2×2布局
46宫格6232×3布局
59宫格933经典3×3布局
6横向2图212横向拼接
7横向3图313横向拼接
8纵向2图221纵向拼接
9纵向3图331纵向拼接
10左1右2322左侧大图右侧小图
11上1下2322上方大图下方小图

1.4 边框样式定义

序号样式名称宽度描述
1无边框0px图片无缝拼接
2细边框2px细线分隔
3中等4px适中边框
4粗边框8px明显分隔

1.5 圆角样式定义

序号样式名称圆角描述
1直角0px锐利边角
2小圆角8px微微圆润
3中圆角16px适中圆角
4大圆角32px明显圆角
5圆形100px完全圆形

1.6 拼图比例定义

序号比例名称比例值适用场景
1正方形1:1Instagram、头像
24:34:3传统照片
33:43:4竖版照片
416:916:9宽屏展示
59:169:16手机壁纸

1.7 技术栈

技术领域技术选型版本要求
开发框架Flutter>= 3.0.0
编程语言Dart>= 2.17.0
设计规范Material Design 3-
图片选择image_picker>= 1.0.4
图片处理image>= 4.1.7
图片保存image_gallery_saver>= 2.0.3
分享功能share_plus>= 7.2.2
目标平台鸿蒙OS / Android / iOSAPI 21+

1.8 项目结构

lib/
└── main_image_collage.dart
    ├── ImageCollageApp               # 应用入口
    ├── CollageTemplate               # 拼图模板枚举
    ├── BorderStyle                   # 边框样式枚举
    ├── CornerStyle                   # 圆角样式枚举
    ├── CollageRatio                  # 拼图比例枚举
    ├── CollageImage                  # 图片信息模型
    ├── ImageCollageHomePage          # 主页面(底部导航)
    ├── _buildCreatePage              # 创建页面
    ├── _buildTemplatesPage           # 模板页面
    ├── _buildHistoryPage             # 历史记录页
    ├── _buildSettingsPage            # 设置页
    ├── _generateCollageImage         # 生成拼图图片
    └── _buildCollageGrid             # 拼图网格预览

二、系统架构

2.1 整体架构图

Data Layer

Business Layer

Presentation Layer

主页面
ImageCollageHomePage

创建页

模板页

历史页

设置页

模板选择器

拼图预览

图片选择器

样式设置

模板网格

历史列表

图片选择器
ImagePicker

拼图生成器
CollageGenerator

保存管理器
SaveManager

CollageImage
图片信息

CollageTemplate
拼图模板

BorderStyle
边框样式

CornerStyle
圆角样式

CollageRatio
拼图比例

2.2 类图设计

uses

uses

uses

uses

manages

ImageCollageApp

+Widget build()

«enumeration»

CollageTemplate

+String label

+int count

+int rows

+int cols

+IconData icon

+grid2()

+grid3()

+grid4()

+grid6()

+grid9()

+horizontal2()

+horizontal3()

+vertical2()

+vertical3()

+left1right2()

+top1bottom2()

«enumeration»

BorderStyle

+String label

+double width

+none()

+thin()

+medium()

+thick()

«enumeration»

CornerStyle

+String label

+double radius

+none()

+small()

+medium()

+large()

+round()

«enumeration»

CollageRatio

+String label

+double ratio

+square()

+ratio43()

+ratio34()

+ratio169()

+ratio916()

CollageImage

+String id

+File file

+String name

+int order

ImageCollageHomePage

-int _currentIndex

-List<CollageImage> _selectedImages

-CollageTemplate _selectedTemplate

-BorderStyle _borderStyle

-CornerStyle _cornerStyle

-CollageRatio _collageRatio

+pickImages()

+removeImage()

+reorderImages()

+generateCollageImage()

+saveCollage()

+shareCollage()

2.3 页面导航流程

边框

圆角

比例

背景

保存

分享

重排

应用启动

创建页

选择模板

选择图片

预览拼图

调整样式

设置边框样式

设置圆角效果

设置拼图比例

设置背景颜色

操作选择

保存到相册

分享拼图

拖拽调整顺序

模板页

浏览所有模板

选择模板

历史页

查看历史拼图

2.4 拼图生成流程

文件系统 拼图生成器 创建页 用户 文件系统 拼图生成器 创建页 用户 loop [处理每张图片] 选择模板和图片 显示拼图预览 点击保存/分享 生成拼图图片 计算画布尺寸 填充背景颜色 读取原图 返回图片数据 解码图片 调整尺寸 合成到画布 保存拼图文件 返回文件路径 保存/分享成功

三、核心模块设计

3.1 数据模型设计

3.1.1 拼图模板枚举 (CollageTemplate)
enum CollageTemplate {
  grid2(label: '2宫格', count: 2, rows: 1, cols: 2, icon: Icons.grid_view),
  grid3(label: '3宫格', count: 3, rows: 1, cols: 3, icon: Icons.view_week),
  grid4(label: '4宫格', count: 4, rows: 2, cols: 2, icon: Icons.grid_4x4),
  grid6(label: '6宫格', count: 6, rows: 2, cols: 3, icon: Icons.apps),
  grid9(label: '9宫格', count: 9, rows: 3, cols: 3, icon: Icons.apps_outlined),
  // ... 其他模板

  final String label;
  final int count;
  final int rows;
  final int cols;
  final IconData icon;
  const CollageTemplate({
    required this.label,
    required this.count,
    required this.rows,
    required this.cols,
    required this.icon,
  });
}
3.1.2 边框样式枚举 (BorderStyle)
enum BorderStyle {
  none(label: '无边框', width: 0),
  thin(label: '细边框', width: 2),
  medium(label: '中等', width: 4),
  thick(label: '粗边框', width: 8);

  final String label;
  final double width;
  const BorderStyle({
    required this.label,
    required this.width,
  });
}
3.1.3 图片信息模型 (CollageImage)
class CollageImage {
  final String id;
  final File file;
  final String name;
  final int order;

  const CollageImage({
    required this.id,
    required this.file,
    required this.name,
    required this.order,
  });
}
3.1.4 模板使用分布
35% 25% 15% 15% 10% 拼图模板使用分布示例 4宫格 9宫格 6宫格 2宫格 其他

3.2 页面结构设计

3.2.1 主页面布局

ImageCollageHomePage

IndexedStack

创建页

模板页

历史页

设置页

NavigationBar

创建 Tab

模板 Tab

历史 Tab

设置 Tab

3.2.2 创建页结构

创建页

SliverAppBar

模板选择器

拼图预览

图片选择器

样式设置

操作按钮

横向滚动模板列表

拼图网格预览

可排序列表

拖拽排序

边框样式

圆角样式

拼图比例

背景颜色

3.2.3 模板页结构

模板页

SliverAppBar

模板网格

3列网格布局

模板卡片

图标

名称

图片数

3.3 拼图生成逻辑

左1右2

上1下2

普通

开始生成

计算画布尺寸

创建空白画布

填充背景颜色

遍历图片列表

读取图片文件

解码图片数据

计算单元格位置

特殊模板?

左侧大图右侧小图

上方大图下方小图

标准网格布局

调整图片尺寸

合成到画布

还有图片?

编码输出图片

返回结果

3.4 图片排序逻辑

拖拽开始

记录起始位置

拖拽移动

更新视觉位置

拖拽结束

获取目标位置

移除原位置元素

插入到新位置

更新所有元素顺序

刷新UI


四、UI设计规范

4.1 配色方案

应用以活力的粉色为主色调,象征创意与活力:

颜色类型色值用途
主色#E91E63 (Pink)导航、主题元素
辅助色#F48FB1次要按钮
第三色#FCE4EC背景装饰
强调色#C2185B重要操作
背景色#FAFAFA页面背景
卡片背景#FFFFFF信息卡片
成功色#4CAF50保存成功
分享色#2196F3分享按钮

4.2 模板配色

模板类型背景色建议适用场景
4宫格白色/黑色日常拼图
9宫格白色社交分享
横向拼接黑色风景展示
纵向拼接白色人物展示
特殊模板灰色创意拼图

4.3 字体规范

元素字号字重颜色
页面标题24pxBold主色
模板名称14pxBold黑色
图片数量12pxRegular灰色
按钮文字14pxMedium白色
提示文字12pxRegular灰色

4.4 组件规范

4.4.1 模板选择器
┌─────────────────────────────────────┐
│  选择模板                    3/4     │
│                                     │
│  ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐    │
│  │ ▦ │ │ ▦ │ │ ▦ │ │ ▦ │ │ ▦ │    │
│  │2格│ │3格│ │4格│ │6格│ │9格│    │
│  └───┘ └───┘ └───┘ └───┘ └───┘    │
└─────────────────────────────────────┘
4.4.2 拼图预览
┌─────────────────────────────────────┐
│  拼图预览                              │
│                                     │
│  ┌─────────────────────────────┐   │
│  │  ┌─────┐ ┌─────┐ ┌─────┐   │   │
│  │  │     │ │     │ │     │   │   │
│  │  │ 图1 │ │ 图2 │ │ 图3 │   │   │
│  │  │     │ │     │ │     │   │   │
│  │  └─────┘ └─────┘ └─────┘   │   │
│  │  ┌─────┐ ┌─────┐ ┌─────┐   │   │
│  │  │     │ │     │ │     │   │   │
│  │  │ 图4 │ │ 图5 │ │ 图6 │   │   │
│  │  │     │ │     │ │     │   │   │
│  │  └─────┘ └─────┘ └─────┘   │   │
│  └─────────────────────────────┘   │
└─────────────────────────────────────┘
4.4.3 图片选择器
┌─────────────────────────────────────┐
│  已选图片          [添加] [清空]      │
│                                     │
│  ≡ [图片] image_001.jpg      ✕      │
│           位置 1                     │
│                                     │
│  ≡ [图片] image_002.jpg      ✕      │
│           位置 2                     │
│                                     │
│  ≡ [图片] image_003.jpg      ✕      │
│           位置 3                     │
└─────────────────────────────────────┘
4.4.4 样式设置
┌─────────────────────────────────────┐
│  样式设置                              │
│                                     │
│  边框样式                             │
│  [无边框] [细边框] [中等] [粗边框]     │
│                                     │
│  圆角样式                             │
│  [直角] [小圆角] [中圆角] [大圆角] [圆形]│
│                                     │
│  拼图比例                             │
│  [正方形] [4:3] [3:4] [16:9] [9:16]  │
│                                     │
│  背景颜色                             │
│  ●     ○     ○     ○     ○          │
│ 黑色  白色  灰色  蓝色  粉色          │
└─────────────────────────────────────┘
4.4.5 操作按钮
┌─────────────────────────────────────┐
│                                     │
│      [💾 保存到相册]                 │
│                                     │
│      [📤 分享拼图]                   │
│                                     │
└─────────────────────────────────────┘

五、核心功能实现

5.1 图片选择实现

Future<void> _pickImages() async {
  try {
    final remaining = _selectedTemplate.count - _selectedImages.length;
    if (remaining <= 0) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('已达到模板最大图片数')),
      );
      return;
    }

    final List<XFile> images = await _imagePicker.pickMultiImage();
    if (images.isEmpty) return;

    int addedCount = 0;
    for (var image in images) {
      if (_selectedImages.length >= _selectedTemplate.count) break;

      final collageImage = CollageImage(
        id: 'img_${DateTime.now().millisecondsSinceEpoch}_${image.name}',
        file: File(image.path),
        name: image.name,
        order: _selectedImages.length,
      );

      setState(() {
        _selectedImages.add(collageImage);
      });
      addedCount++;
    }
  } catch (e) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('选择图片失败: $e')),
    );
  }
}

5.2 拼图生成实现

Future<img.Image?> _generateCollageImage() async {
  if (_selectedImages.isEmpty) return null;

  final outputSize = 1200;
  final borderPx = _borderStyle.width.toInt();

  final totalWidth = outputSize;
  final totalHeight = _collageRatio.ratio >= 1
      ? (outputSize / _collageRatio.ratio).round()
      : outputSize;

  final result = img.Image(width: totalWidth, height: totalHeight);

  // 填充背景
  final bgColor = img.ColorRgba8(
    _backgroundColor.red,
    _backgroundColor.green,
    _backgroundColor.blue,
    255,
  );
  img.fill(result, color: bgColor);

  final template = _selectedTemplate;
  final cols = template.cols;
  final rows = template.rows;

  final cellWidth = (totalWidth - borderPx * (cols + 1)) ~/ cols;
  final cellHeight = (totalHeight - borderPx * (rows + 1)) ~/ rows;

  for (int i = 0; i < _selectedImages.length && i < template.count; i++) {
    final imageItem = _selectedImages[i];

    final bytes = await imageItem.file.readAsBytes();
    final decodedImage = img.decodeImage(bytes);
    if (decodedImage == null) continue;

    final row = i ~/ cols;
    final col = i % cols;

    final resizedImage = img.copyResize(
      decodedImage,
      width: cellWidth,
      height: cellHeight,
    );

    final x = borderPx + col * (cellWidth + borderPx);
    final y = borderPx + row * (cellHeight + borderPx);

    img.compositeImage(result, resizedImage, dstX: x, dstY: y);
  }

  return result;
}

5.3 图片排序实现

void _reorderImages(int oldIndex, int newIndex) {
  setState(() {
    if (newIndex > oldIndex) {
      newIndex -= 1;
    }
    final item = _selectedImages.removeAt(oldIndex);
    _selectedImages.insert(newIndex, item);

    // 更新顺序
    for (int i = 0; i < _selectedImages.length; i++) {
      _selectedImages[i] = CollageImage(
        id: _selectedImages[i].id,
        file: _selectedImages[i].file,
        name: _selectedImages[i].name,
        order: i,
      );
    }
  });
}

5.4 保存拼图实现

Future<void> _saveCollage() async {
  if (_selectedImages.isEmpty) return;

  setState(() {
    _isProcessing = true;
  });

  try {
    final collageImage = await _generateCollageImage();
    if (collageImage == null) {
      throw Exception('生成拼图失败');
    }

    final tempDir = await getTemporaryDirectory();
    final filePath = '${tempDir.path}/collage_${DateTime.now().millisecondsSinceEpoch}.png';
    final file = File(filePath);
    await file.writeAsBytes(img.encodePng(collageImage));

    final bytes = await file.readAsBytes();
    final result = await ImageGallerySaver.saveImage(
      bytes,
      quality: 100,
      name: 'collage_${DateTime.now().millisecondsSinceEpoch}',
    );

    setState(() {
      _isProcessing = false;
    });

    if (result['isSuccess'] == true) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('拼图已保存到相册')),
      );
    }
  } catch (e) {
    setState(() {
      _isProcessing = false;
    });
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('保存失败: $e')),
    );
  }
}

5.5 分享拼图实现

Future<void> _shareCollage() async {
  if (_selectedImages.isEmpty) return;

  setState(() {
    _isProcessing = true;
  });

  try {
    final collageImage = await _generateCollageImage();
    if (collageImage == null) {
      throw Exception('生成拼图失败');
    }

    final tempDir = await getTemporaryDirectory();
    final filePath = '${tempDir.path}/collage_share_${DateTime.now().millisecondsSinceEpoch}.png';
    final file = File(filePath);
    await file.writeAsBytes(img.encodePng(collageImage));

    setState(() {
      _isProcessing = false;
    });

    await Share.shareXFiles(
      [XFile(filePath)],
      text: '分享我的拼图',
    );
  } catch (e) {
    setState(() {
      _isProcessing = false;
    });
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('分享失败: $e')),
    );
  }
}

六、交互设计

6.1 图片选择流程

文件系统 图片选择器 创建页 用户 文件系统 图片选择器 创建页 用户 loop [处理每张图- 片] 点击添加图片 打开相册 显示图片列表 选择图片 返回选中图片 创建CollageImage 添加到列表 显示已选图片

6.2 拼图生成流程

点击保存/分享

是否有图片?

提示选择图片

设置处理状态

计算画布尺寸

创建空白画布

填充背景颜色

遍历图片列表

读取原图

解码图片

计算位置尺寸

调整图片大小

合成到画布

还有图片?

编码输出PNG

保存/分享文件

6.3 样式调整流程

满意

满意

选择模板

选择图片

预览拼图

调整边框

调整圆角

调整比例

调整背景

保存拼图

分享拼图


七、扩展功能规划

7.1 后续版本规划

2024-01-07 2024-01-14 2024-01-21 2024-01-28 2024-02-04 2024-02-11 2024-02-18 2024-02-25 2024-03-03 2024-03-10 2024-03-17 2024-03-24 2024-03-31 2024-04-07 基础UI框架 模板选择功能 拼图生成功能 更多模板 滤镜效果 文字贴纸 自由拼图 智能布局 模板社区 V1.0 基础版本 V1.1 增强版本 V1.2 进阶版本 图片拼图工具开发计划

7.2 功能扩展建议

7.2.1 滤镜效果

滤镜功能:

  • 亮度对比度调整
  • 色彩饱和度
  • 复古滤镜
  • 黑白滤镜
7.2.2 文字贴纸

贴纸功能:

  • 添加文字
  • 表情贴纸
  • 日期水印
  • 自定义贴纸
7.2.3 自由拼图

自由功能:

  • 自由拖拽位置
  • 自由缩放大小
  • 图层管理
  • 自定义模板保存

八、注意事项

8.1 开发注意事项

  1. 内存管理:处理大图片时注意内存释放

  2. 权限申请:确保存储权限正确申请

  3. 图片质量:输出高质量拼图图片

  4. 模板适配:特殊模板需要单独处理布局逻辑

  5. 用户体验:实时预览拼图效果

8.2 常见问题

问题原因解决方案
图片选择失败权限未授予引导用户授权
拼图生成失败内存不足分批处理图片
保存失败存储空间不足提示清理空间
图片变形比例不匹配使用cover模式
预览卡顿图片过大压缩预览图

8.3 使用技巧

🖼️ 图片拼图工具使用技巧 🖼️

选择技巧

  • 根据图片数量选择模板
  • 注意图片比例一致性
  • 选择合适的拼图比例
  • 预览效果再保存

排版技巧

  • 重要图片放显眼位置
  • 色彩搭配要协调
  • 适当使用边框分隔
  • 背景色与图片呼应

分享技巧

  • 选择适合平台的比例
  • 注意图片清晰度
  • 添加文字说明
  • 选择合适时机分享

九、运行说明

9.1 环境要求

环境版本要求
Flutter SDK>= 3.0.0
Dart SDK>= 2.17.0
鸿蒙OSAPI 21+
AndroidAPI 21+
iOS12.0+

9.2 依赖配置

pubspec.yaml 中添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  image_picker: ^1.0.4
  image: ^4.1.7
  image_gallery_saver: ^2.0.3
  share_plus: ^7.2.2
  path_provider: ^2.1.4

9.3 运行命令

# 查看可用设备
flutter devices

# 运行到Web服务器
flutter run -d web-server -t lib/main_image_collage.dart --web-port 8148

# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 lib/main_image_collage.dart

# 运行到Android设备
flutter run -d android lib/main_image_collage.dart

# 代码分析
flutter analyze lib/main_image_collage.dart

9.4 权限配置

Android权限 (android/app/src/main/AndroidManifest.xml)
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
iOS权限 (ios/Runner/Info.plist)
<key>NSPhotoLibraryUsageDescription</key>
<string>需要相册权限选择和保存图片</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>需要相册权限保存拼图</string>

十、总结

图片拼图工具应用通过整合图片选择、模板选择、样式设置、拼图生成、保存分享等功能,为用户提供了一站式的图片拼接解决方案。应用支持11种拼图模板,涵盖2-9张图片的灵活组合,用户可自定义边框样式、圆角效果、拼图比例和背景颜色,打造独一无二的拼图效果。

核心功能涵盖图片选择、模板选择、边框样式、圆角效果、拼图比例、背景颜色、图片排序、保存相册、分享功能九大模块。用户可以轻松选择图片、挑选模板、调整样式、生成拼图,实现图片的创意组合。

应用采用 Material Design 3 设计规范,以活力的粉色为主色调,象征创意与活力。通过本应用,希望能够帮助用户更高效地进行图片拼图创作,让美好瞬间更加精彩。

图片拼图工具——让创意无限可能


Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐