uni-app 图片视频相册选择后图片无法预览,拍照的可以预览,image标签可以看见但预览图片功能失效
uni-app 图片视频相册选择后图片无法预览,拍照的可以预览,image标签可以看见但预览图片功能失效
| 开发环境 | 版本号 | 项目创建方式 |
|---|---|---|
| Windows | win11 | HBuilderX |
产品分类:uniapp/App
PC开发环境操作系统:Windows
HBuilderX类型:正式
HBuilderX版本号:3.2.14
手机系统:Android
手机系统版本号:Android 8.1
手机厂商:华为
手机机型:BKK-AL10
页面类型:vue
vue版本:vue2
打包方式:云端
项目创建方式:HBuilderX
示例代码:
<template>
<view class="upload">
<view class="box" v-for="(item,index) in uploadData" :key="index">
<div class="img" v-if="item.type=='img'">
<image @tap="tup(item.img)" class="images" :src="item.img" style="100%;height: 100%;" mode="aspectFill"></image>
<div class="get">重试</div>
<div class="prog">100%</div>
<div class="close myiconfont iconguanbi" @tap="close(index)"></div>
</div>
<div v-else class="video">
<image @tap="nav('../../pagesservice/video/video?src='+item.img)" v-if="item.prog!=100" class="images" src="../../static/video.png" style="width: 150rpx;height: 150rpx;"></image>
<div class="get">重试</div>
<div class="prog">100%</div>
<div class="close myiconfont iconguanbi" @tap="close(index)"></div>
<div v-if="item.prog==100" class="bof myiconfont iconbofangiconx" @tap="nav('../../pagesservice/video/video?src='+item.img)"></div>
</div>
</view>
<div class="defbox" @tap="get">
<div class="top myiconfont iconjia"></div>
<div class="name">{{name}}</div>
</div>
<div class="defboxbai"></div>
<div class="defboxbai"></div>
<u-action-sheet @click="click" :list="list" v-model="show"></u-action-sheet>
</view>
</template>
<script>
export default {
data() {
return {
action:'',//上传地址
formData:'',//额外数据
img:[],
list: [
// {
// text: '点赞',
// color: 'blue',
// fontSize: 28,
// subText: '感谢您的点赞'
// },
{
text: '拍照'
}, {
text: '拍摄'
}, {
text: '从相册里选择图片'
}, {
text: '从相册里选择视频'
}],
show: false,
name:'图片/视频上传',
uploadData:[]
};
},
methods:{
tup:function(src){
console.log(src,this.img);
uni.previewImage({
current:src,
urls: this.img,
longPressActions: {
itemList: ['发送给朋友', '保存图片', '收藏'],
success: function(data) {
console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片');
},
fail: function(err) {
console.log(err.errMsg);
}
}
});
},
close:function(id){
uni.showModal({
title: '删除提示',
content: '确定要删除该图片/视频?',
success: (res)=> {
if (res.confirm) {
this.uploadData.splice(id,1);
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
},
nav:function(url){
uni.navigateTo({
url:url,
})
},
get:function(){
this.show=true;
},
uplaod:function(){
},
click:function(index) {
console.log(index);
if(index==0){//拍照
uni.chooseImage({
count: 6, //默认9
sizeType: ['original'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['camera'],
success: (res)=>{
var obj={
type:'img',
img:res.tempFilePaths[0],
prog:0,
retry:false,
this:'',
};
this.img.push(res.tempFilePaths[0]);
this.uploadData.push(obj);
}
});
}else if(index==1){//拍摄
uni.chooseVideo({
count: 1,
sourceType: ['camera'],
success: (res)=>{
var obj={
type:'video',
img:res.tempFilePath,
prog:0,
retry:false,
this:'',
};
this.uploadData.push(obj);
}
});
}else if(index==2){//相册选择照片
uni.chooseImage({
count: 6, //默认9
sizeType: ['original'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album'], //从相册选择
success: (res)=>{
console.log(res);
res.tempFilePaths.forEach((item,id)=>{
var obj={
type:'img',
img:item,
prog:0,
retry:false,
this:'',
};
this.img.push(item);
this.uploadData.push(obj);
});
}
});
}else if(index==3){//相册选择视频
uni.chooseVideo({
sizeType: ['original'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album'], //从相册选择
success: (res)=>{
var obj={
type:'video',
img:res.tempFilePath,
prog:0,
retry:false,
this:'',
};
this.uploadData.push(obj);
}
});
}
}
}
}
</script>
<style lang="scss">
.upload{
width: 100%;
display: flex;
justify-content: space-around;
flex-wrap: wrap;
.box{
margin:10rpx 0rpx;
display: flex;
justify-content: center;
flex-wrap: wrap;
align-items: center;
align-content: center;
width: 200rpx;
height: 200rpx;
background-color: #eee;
border:1px solid #ddd;
.img{
width: 200rpx;
height: 200rpx;
position: relative;
.images{
position: absolute;
top:0rpx;
left:0rpx;
z-index: 7;
width: 200rpx;
height: 200rpx;
}
.get{
width: 100%;
position: absolute;
bottom:0rpx;
left:0rpx;
z-index: 8;
background-color: red;
font-size: 26rpx;
color:#fff;
text-align: center;
line-height: 40rpx;
height: 40rpx;
}
.prog{
width: 100%;
position: absolute;
bottom:0rpx;
left:0rpx;
z-index: 8;
background-color: $uni-color-success;
font-size: 26rpx;
color:#fff;
text-align: center;
line-height: 40rpx;
height: 40rpx;
}
.close{
width: 40rpx;
position: absolute;
top:-10rpx;
right:-10rpx;
z-index: 8;
background-color: red;
font-size: 32rpx;
color:#fff;
text-align: center;
line-height: 40rpx;
height: 40rpx;
border-radius: 40rpx;
}
}
.video{
width: 200rpx;
height: 200rpx;
position: relative;
.images{
width: 200rpx;
height: 200rpx;
position: absolute;
top:0rpx;
left:0rpx;
right:0rpx;
bottom:0rpx;
margin:auto;
z-index: 7;
}
.get{
width: 100%;
position: absolute;
bottom:0rpx;
left:0rpx;
z-index: 8;
background-color: red;
font-size: 26rpx;
color:#fff;
text-align: center;
line-height: 40rpx;
height: 40rpx;
}
.prog{
width: 100%;
position: absolute;
bottom:0rpx;
left:0rpx;
z-index: 8;
background-color: $uni-color-success;
font-size: 26rpx;
color:#fff;
text-align: center;
line-height: 40rpx;
height: 40rpx;
}
.close{
width: 40rpx;
position: absolute;
top:-10rpx;
right:-10rpx;
z-index: 8;
background-color: red;
font-size: 32rpx;
color:#fff;
text-align: center;
line-height: 40rpx;
height: 40rpx;
border-radius: 40rpx;
}
.bof{
width: 100rpx;
position: absolute;
top:0rpx;
right:0rpx;
bottom:0rpx;
left:0rpx;
z-index: 8;
font-size: 52rpx;
color:#fff;
text-align: center;
line-height: 100rpx;
height: 100rpx;
margin:auto;
border-radius: 100rpx;
}
}
}
.defboxbai{
width: 200rpx;
height: 200rpx;
}
.defbox{
margin:10rpx 0rpx;
display: flex;
justify-content: center;
flex-wrap: wrap;
align-items: center;
align-content: center;
width: 200rpx;
height: 200rpx;
background-color: #eee;
border:1px solid #ddd;
.top{
width: 100%;
font-size: 82rpx;
height: 50rpx;
line-height: 20rpx;
text-align: center;
color:#888;
}
.name{
width: 100%;
font-size: 30rpx;
height: 50rpx;
line-height: 50rpx;
text-align: center;
color:#888;
}
}
}
</style>
操作步骤:
- 还是一样
预期结果:
- 还是一样,不行
实际结果:
- 打包后还是一样
bug描述:
-
相册选择返回的图片路径:
file:///storage/3931-3334/Program Files (x86)/WiFiMasterKey/Help/mobile_help/img/002.jpg -
拍照图片返回的路径:
_doc/uniapp_temp_1637208838291/camera/1637209287241.jpg -
相册的图片的
uni.previewImage()无法预览,但是拍照的可以
更多关于uni-app 图片视频相册选择后图片无法预览,拍照的可以预览,image标签可以看见但预览图片功能失效的实战教程也可以访问 https://www.itying.com/category-93-b0.html
问题出在相册选择的图片路径格式上。从相册选择的图片返回的是 file:// 开头的本地文件路径,而 uni.previewImage 在 Android 平台上不支持直接使用这种格式的路径进行预览。
拍照返回的路径格式 _doc/uniapp_temp_... 是应用私有目录路径,可以被正常预览。
解决方案:
- 使用临时文件路径:将相册选择的图片复制到应用临时目录
// 修改相册选择照片的成功回调
success: (res) => {
res.tempFilePaths.forEach((item, id) => {
// 将文件复制到应用临时目录
const tempFilePath = `${plus.io.convertLocalFileSystemURL(item)}`;
var obj = {
type: 'img',
img: tempFilePath, // 使用转换后的路径
prog: 0,
retry: false,
this: '',
};
this.img.push(tempFilePath);
this.uploadData.push(obj);
});
}
- 或者使用更简单的方法:直接使用
res.tempFilePaths中的路径,但需要确保路径格式正确
实际上,uni.chooseImage 返回的 tempFilePaths 应该已经是可用的临时路径。问题可能是路径格式不一致导致的。
检查你的代码逻辑:在 tup 方法中,你使用 this.img 数组作为 urls 参数,但要注意数组中的路径格式必须一致。
建议的修复方案:
tup: function(src) {
// 统一使用临时路径数组
const previewUrls = this.uploadData
.filter(item => item.type === 'img')
.map(item => item.img);
uni.previewImage({
current: src,
urls: previewUrls,
longPressActions: {
itemList: ['发送给朋友', '保存图片', '收藏'],
success: function(data) {
console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片');
},
fail: function(err) {
console.log(err.errMsg);
}
}
});
}
同时确保在相册选择时,路径处理正确:
// 相册选择照片时
success: (res) => {
console.log('相册选择返回的路径:', res.tempFilePaths);
res.tempFilePaths.forEach((item, id) => {
// 直接使用返回的临时路径
var obj = {
type: 'img',
img: item, // 直接使用tempFilePaths中的路径
prog: 0,
retry: false,
};
this.uploadData.push(obj);
});
// 更新预览用的图片数组
this.img = this.uploadData
.filter(item => item.type === 'img')
.map(item => item.img);
}


