更新记录

1.0.0(2026-11-12)

  • 首次发布:iOS / Android 仿微信选图页(相册切换、多选序号、大图预览、原图、视频试看、原生图片编辑)
  • 参数:count、mediaType、maxImageCount、maxVideoCount、mixSelect、maxDuration、minDuration、maxVideoSize、showOriginal、defaultOriginal、editable、videoPlayable、columns、themeColor、confirmText、cancelText、compressQuality、compressMaxSide、haptic
  • 鸿蒙调用系统选择器 PhotoViewPicker

平台兼容性

uni-app x(5.31)

Chrome Safari Android iOS 鸿蒙 微信小程序
× × 5.0 15 12 ×

其他

多语言 暗黑模式 宽屏模式 蒸汽模式
× × √ √

tlink-photo-picker 仿微信图片 / 视频选择器

uni-app x 原生选图插件。原生层读取系统相册,界面是插件自带的 uvue 页面,交互对齐微信。

目录

功能

iOS / Android:

  • 相册列表:顶部胶囊切换相册,第一项为「最近项目」,空相册不显示
  • 多选:带序号;跨相册保留已选;可限制总数、图片数、视频数,可禁止图片视频混选
  • 视频:显示时长角标,可限制最短、最长时长和最大文件大小,支持预览中试看
  • 大图预览:左右翻页(可在整个相册里连续翻),双击放大,双指缩放,单击显隐上下栏;底部已选缩略图条,点击跳转
  • 原图开关:可隐藏,可设默认勾选
  • 图片编辑(原生页面):涂鸦、表情、文字、裁剪旋转、马赛克;编辑后自动勾选,缩略图换成编辑结果
  • 可选压缩:未勾原图时按质量和长边压缩,GIF 跳过
  • 主题色、按钮文字、网格列数可配置;宽屏(≥ 600px)自动 6 列
  • iOS「部分照片」授权:顶部提示条和「管理」入口;Android 13 分媒体权限、14「部分照片」
  • 缩略图按滚动位置流式生成,万张图库不卡;HEIC 自动转 JPEG,GIF / PNG / JPEG 原样导出

平台支持

平台 支持 实现
uni-app x iOS iOS 15+ 自建选图页(Photos / PhotosUI)
uni-app x Android Android 5.0+(minSdk 21) 自建选图页(MediaStore)
uni-app x 鸿蒙 √(功能精简) 系统选择器 PhotoViewPicker,免权限
uni-app x Web / 小程序 × 调用直接走 fail(errCode 2)
uni-app(Vue 版) × 不支持

安装

  1. 在插件市场导入插件。HBuilderX 会提示把选图页合并进 pages.json,选「合并」。
  2. 没有合并时,手动在 pages.json 的 pages 数组里加(不能放首位):
{
    "path": "uni_modules/tlink-photo-picker/pages/picker/picker",
    "style": {
        "navigationBarTitleText": "选择图片",
        "navigationStyle": "custom",
        "navigationBarTextStyle": "white",
        "disableSwipeBack": true
    }
}
  1. 视频试看用到 video 组件:在 manifest.json 的「App 模块配置」里勾选 Video(或在源码视图 app-android / app-ios 的 distribute.modules 中加 "uni-video": {})。
  2. 插件含原生代码,必须重新制作自定义基座后运行,标准基座不可用。付费插件试用也只能在自定义基座上进行。

快速开始

import {
    chooseMedia,
    TLChooseMediaResult,
    TLChooseMediaFail
} from '@/uni_modules/tlink-photo-picker/common/index.uts'

chooseMedia({
    count: 9,
    success: (res : TLChooseMediaResult) => {
        for (let i = 0; i < res.tempFiles.length; i++) {
            const f = res.tempFiles[i]
            console.log(f.type, f.path, f.width, f.height, f.size)
        }
    },
    fail: (err : TLChooseMediaFail) => {
        if (err.errCode != 1) {
            uni.showToast({ title: err.errMsg, icon: 'none' })
        }
    }
})

chooseMedia 参数

chooseMedia(options : TLChooseMediaOptions) : void,所有参数都可省略。

选择范围

参数 类型 默认值 说明
count number 9 最多选几项(图片 + 视频合计),最小 1
mediaType string 'mix' 'mix' 图片和视频;'image' 只显示图片;'video' 只显示视频
maxImageCount number 0 图片最多几张,0 表示只受 count 限制
maxVideoCount number 0 视频最多几个,0 表示只受 count 限制
mixSelect boolean true 是否允许图片和视频混选。false 时选了图片后视频置灰,反之亦然(类似朋友圈)

视频限制

参数 类型 默认值 说明
maxDuration number 0 视频最长秒数,超出时点击提示「只能选择 X 以内的视频」;0 不限
minDuration number 0 视频最短秒数,不足时提示「只能选择 X 以上的视频」;0 不限
maxVideoSize number 0 视频最大字节数。超出的视频仍会返回,但 path 为空串、size 为实际大小,方便你提示「文件过大」;0 不限
videoPlayable boolean true 预览中视频是否显示播放按钮试看

原图与压缩

参数 类型 默认值 说明
showOriginal boolean true 是否显示「原图」开关。隐藏时 original 恒为 false
defaultOriginal boolean false 「原图」默认是否勾选(showOriginal 为 false 时无效)
compressQuality number 0 未勾原图时的图片压缩质量 1-100;0 不压缩,原样返回原尺寸文件。GIF 不压缩
compressMaxSide number 1600 压缩时长边上限(px),超过的等比缩小;0 只降质量不缩放。compressQuality 为 0 时无效

不开压缩时插件不处理图片:勾不勾原图都返回原尺寸文件,你可以根据 original 自行压缩。

编辑

参数 类型 默认值 说明
editable boolean true 预览中图片是否显示「编辑」入口(涂鸦 / 表情 / 文字 / 裁剪旋转 / 马赛克)

界面

参数 类型 默认值 说明
themeColor string '#07C160' 主题色,作用于勾选序号、完成按钮、原图开关、当前相册勾、预览缩略图条描边、「管理」文字
confirmText string '完成' 完成按钮文字,选中后自动显示为「完成(3)」
cancelText string '取消' 左上角取消文字
columns number 0 网格列数 1-8;0 自动:窗口宽度 < 600px 为 4 列,否则 6 列
haptic boolean false 点击时轻震(uni.vibrateShort);基座不含震动模块时静默跳过

回调

参数 类型 说明
success (res : TLChooseMediaResult) => void 选择完成。开了压缩时在压缩结束后回调
fail (err : TLChooseMediaFail) => void 取消或失败,见错误码
complete () => void 成功或失败后都会调用

success 返回值

TLChooseMediaResult

字段 类型 说明
original boolean 用户是否勾选了「原图」
tempFiles TLMediaFile[] 选中的文件,顺序与勾选序号一致

TLMediaFile

字段 类型 说明
type string 'image' 或 'video'
path string 本地绝对路径,可直接给 image、video、uni.uploadFile;视频超过 maxVideoSize 时为空串
width number 宽(px)。编辑过的是编辑后尺寸,压缩过的是压缩后尺寸
height number 高(px)
duration number 视频时长(秒),图片为 0
size number 文件字节数
compressed boolean 是否经过插件压缩

文件格式:GIF / JPEG / PNG 原样导出,HEIC / HEIF 等其他图片格式转为原尺寸 JPEG;编辑过的图片为 JPEG;视频为原文件拷贝。

fail 错误码

TLChooseMediaFail:{ errCode : number, errMsg : string },errMsg 以 chooseMedia:fail 开头。

errCode 含义 建议处理
1 用户取消(点取消、返回,或鸿蒙选择器里没选) 忽略
2 当前平台不支持(Web、小程序) 改用 uni.chooseImage
3 打开选图页失败 检查 pages.json 是否注册了选图页
4 没有相册权限,用户没去开启就离开了 可引导到系统设置
5 已有选图页打开(重复调用) 忽略,防连点

常用场景示例

聊天发图(同微信)

chooseMedia({
    count: 9,
    maxDuration: 300,
    maxVideoSize: 1024 * 1024 * 1024,
    confirmText: '发送',
    compressQuality: 80,
    compressMaxSide: 1600,
    success: (res) => {
        for (let i = 0; i < res.tempFiles.length; i++) {
            const f = res.tempFiles[i]
            if (f.type == 'video' && f.path.length == 0) {
                uni.showToast({ title: '视频超过 1GB,无法发送', icon: 'none' })
                continue
            }
            // 上传 f.path
        }
    }
})

朋友圈:图片最多 9 张、视频只能 1 个、不能混选

chooseMedia({
    count: 9,
    maxVideoCount: 1,
    mixSelect: false,
    maxDuration: 30,
    minDuration: 3
})

换头像:单张图片,不要原图和视频

chooseMedia({
    count: 1,
    mediaType: 'image',
    showOriginal: false,
    compressQuality: 85,
    compressMaxSide: 800,
    success: (res) => {
        const path = res.tempFiles[0].path
    }
})

只选视频、不允许编辑和试看、自定义主题

chooseMedia({
    mediaType: 'video',
    count: 3,
    videoPlayable: false,
    editable: false,
    themeColor: '#2B7CFF',
    confirmText: '下一步',
    cancelText: '关闭'
})

各平台差异

能力 iOS Android 鸿蒙
自建选图界面 √ √ ×(系统选择器)
count / mediaType √ √ √
maxImageCount / maxVideoCount / mixSelect √ √ ×
maxDuration / minDuration √ √ ×
maxVideoSize √ √ √
原图开关(showOriginal / defaultOriginal) √ √ ×(original 恒为 false)
compressQuality / compressMaxSide √ √ √
编辑、试看、主题色、文字、列数、轻震 √ √ ×
返回 width / height √ √ 图片 √,视频为 0
返回 duration √ √ 0,需要时用 uni.getVideoInfo

权限与隐私

iOS

  • 插件的 utssdk/app-ios/info.plist 已带 NSPhotoLibraryUsageDescription,默认文案为「需要访问你的相册,以便选择照片和视频」,需要修改时直接改该文件。
  • 同一文件设置了 PHPhotoLibraryPreventAutomaticLimitedAccessAlert = true,关闭系统在「部分照片」授权下的自动提示(对整个 App 生效),由选图页顶部的「管理」入口替代。
  • 首次打开选图页才申请权限。

Android

  • 插件声明的权限:READ_EXTERNAL_STORAGE(Android 12 及以下)、READ_MEDIA_IMAGES、READ_MEDIA_VIDEO(13+)、READ_MEDIA_VISUAL_USER_SELECTED(14+ 部分照片)。
  • 首次打开选图页才申请。国内应用市场上架时,需在隐私政策中说明相册用途,并按市场要求在申请前展示用途说明。
  • 用户拒绝后,选图页显示「去设置」按钮,并弹框引导到系统设置。

鸿蒙

  • 使用系统 PhotoViewPicker,不需要声明任何权限。

数据

  • 插件不联网、不采集任何数据。
  • 选中的文件拷贝到本应用缓存目录:iOS / Android 由插件定期清理旧的导出文件和缩略图缓存,鸿蒙每次选择前清理一天前的文件。需要长期保存时请自行拷贝到 uni.env.USER_DATA_PATH。

底层原生 API

自己画界面时可以直接用原生层。引入:import { ... } from '@/uni_modules/tlink-photo-picker'。跨桥的列表都是 JSON 字符串,自行 JSON.parse。所有回调都在主线程触发。鸿蒙上只有 photoPickSystem 可用,其余为空实现。

函数 说明
photoAuthStatus() : string 相册权限:authorized / limited(部分照片)/ notDetermined / denied。Android 无法区分没问过和拒绝过,统一返回 notDetermined
photoRequestAuth(callback : (status : string) => void) 申请相册权限,回调授权结果(取值同上)
photoManageLimited(callback : () => void) 「部分照片」授权下让用户重新选择可访问的照片,关闭后回调,应重新加载。Android 上系统不再弹框时会跳到应用设置页
photoLoadAlbums(callback : (json : string) => void) 相册列表 [{ id, title, count, cover }]。第一项是「最近项目」(id 为空串),cover 为封面资源 id,空相册不返回
photoLoadAssets(albumId : string, callback : (json : string) => void) 相册内全部图片和视频 [{ id, type, duration }],按拍摄时间倒序;albumId 传空串取「最近项目」
photoSetThumbnailCallback(callback : (key : string, path : string) => void) 挂常驻缩略图回调,每生成一张回调一次。key 为 `${size}#${id}`,path 为本地图片路径
photoClearThumbnailCallback() 摘掉缩略图回调,同时作废本次的编辑结果。页面关闭时调用
photoRequestThumbnails(ids : string[], size : number) 按需生成缩略图,size 为长边像素;已有缓存的立即回调。建议只请求可见区域
photoExportAssets(ids : string[], maxVideoBytes : number, callback : (json : string) => void) 按顺序导出 [{ type, path, width, height, duration, size }],读取失败的项跳过;视频超过 maxVideoBytes 时 path 为空,传 0 不限
photoEditImage(id : string, callback : (json : string) => void) 打开原生编辑页,回调 { status: 'done', path, width, height } / { status: 'cancel' } / { status: 'fail' }。编辑后该资源的缩略图和导出都用编辑结果
photoPickSystem(count : number, mediaType : string, maxVideoBytes : number, callback : (json : string) => void) 仅鸿蒙:系统选择器,回调 [{ type, path, size, width, height }],取消为 []。mediaType 取 mix / image / video

常见问题

调用后没反应 / errCode 3:选图页没注册到 pages.json,按安装第 2 步添加。

报「模块不存在」或原生方法找不到:没有重新打自定义基座,或 iOS 覆盖安装没更新原生库。卸载旧 App 后重新打基座安装。

视频点播放没反应:manifest 没勾选 Video 模块,勾选后重新打基座。

直接 uni.navigateTo 打开选图页拿不到结果:必须通过 chooseMedia 打开,结果走回调。

iOS 只显示部分照片:用户授权的是「部分照片」,点顶部「管理」增减;或引导用户到设置改为「完全访问」。

选图页颜色:固定深色风格(同微信),不跟随系统暗黑模式;主题色可用 themeColor 修改。

多语言:界面文字为中文,按钮文字可通过 confirmText / cancelText 修改,其余暂不支持。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

iOS:NSPhotoLibraryUsageDescription(相册);Android:READ_EXTERNAL_STORAGE、READ_MEDIA_IMAGES、READ_MEDIA_VIDEO、READ_MEDIA_VISUAL_USER_SELECTED;鸿蒙:无(系统选择器免权限)

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据,不联网,不发送到任何服务器。选中的文件仅拷贝到本应用缓存目录。

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

暂无用户评论。