uniapp预览本地图片
问题
在 uniapp 中使用 uni.previewImage 预览项目内的本地图片时,直接传入 static 目录下的图片路径无法正常预览:
uni.previewImage({
urls: ['/static/example.png']
})
因此需要先将本地图片读取并转换为 Base64,再将转换后的数据传递给 uni.previewImage。
解决方案
将图片转换封装成一个跨端函数。微信小程序端使用 uni.getFileSystemManager().readFile 读取文件并转换为 Base64;H5 端则通过 Image + Canvas 获取 Base64 数据。
同时统一使用 Promise 处理异步流程,避免回调与 Promise 混用。
/**
* 图片 MIME Type 映射
*
* Base64 图片除了需要编码后的数据,还需要携带正确的 MIME Type。
* 例如 PNG 图片应使用:
*
* data:image/png;base64,...
*/
const MIME_TYPES: Record<string, string> = {
png: 'image/png',
jpg: 'image/jpeg',
jpeg: 'image/jpeg',
webp: 'image/webp',
gif: 'image/gif'
}
/**
* 将本地图片转换为 Base64
*
* @param filePath 图片路径
* @returns Promise<string> Base64 图片数据
*/
export function imageToBase64(filePath: string): Promise<string> {
return new Promise((resolve, reject) => {
// #ifdef MP-WEIXIN
/**
* 微信小程序可以通过文件系统 API 直接读取本地图片。
*
* encoding 设置为 base64 后,readFile 返回的 data
* 就是图片经过 Base64 编码后的字符串。
*/
uni.getFileSystemManager().readFile({
filePath,
encoding: 'base64',
success: ({ data }) => {
/**
* 根据文件扩展名确定图片类型。
*
* 不能简单地将所有图片都声明为 image/jpeg,
* 否则实际文件类型与 MIME Type 可能不一致。
*/
const extension =
filePath.split('.').pop()?.toLowerCase() || ''
const mimeType = MIME_TYPES[extension] || 'image/jpeg'
/**
* 拼接成标准 Data URL:
*
* data:image/png;base64,xxxxxx
*
* 这种格式可以直接作为图片地址使用。
*/
resolve(`data:${mimeType};base64,${data}`)
},
// 文件读取失败时直接向外抛出异常
fail: reject
})
// #endif
// #ifdef H5
/**
* H5 环境无法使用微信小程序的文件系统 API,
* 因此通过 Image 加载图片,再借助 Canvas 导出 Base64。
*/
const image = new Image()
// 图片加载完成后,将图片绘制到 Canvas
image.onload = () => {
const canvas = document.createElement('canvas')
const context = canvas.getContext('2d')
// 无法获取 Canvas Context 时终止转换
if (!context) {
reject(new Error('无法创建 Canvas Context'))
return
}
// 使用图片的原始尺寸,避免转换过程中改变图片尺寸
canvas.width = image.naturalWidth
canvas.height = image.naturalHeight
// 将图片绘制到 Canvas
context.drawImage(image, 0, 0)
// 导出 Base64 数据
resolve(canvas.toDataURL())
}
// 图片加载失败
image.onerror = () => {
reject(new Error('图片加载失败'))
}
// 开始加载图片
image.src = filePath
// #endif
})
}
使用时直接将转换后的 Base64 传递给 uni.previewImage:
/**
* 预览本地图片
*
* @param filePath 图片路径
*/
export async function previewLocalImage(filePath: string) {
const base64 = await imageToBase64(filePath)
uni.previewImage({
urls: [base64],
current: 0,
loop: true
})
}
这样可以将项目内的本地图片统一转换成 uni.previewImage 可以直接处理的 Base64 数据。

浙公网安备 33010602011771号