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

2 回复

目前测试使用HX3.2.14 真机调试测试一切正常

更多关于uni-app 图片视频相册选择后图片无法预览,拍照的可以预览,image标签可以看见但预览图片功能失效的实战教程也可以访问 https://www.itying.com/category-93-b0.html


问题出在相册选择的图片路径格式上。从相册选择的图片返回的是 file:// 开头的本地文件路径,而 uni.previewImage 在 Android 平台上不支持直接使用这种格式的路径进行预览。

拍照返回的路径格式 _doc/uniapp_temp_... 是应用私有目录路径,可以被正常预览。

解决方案:

  1. 使用临时文件路径:将相册选择的图片复制到应用临时目录
// 修改相册选择照片的成功回调
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);
  });
}
  1. 或者使用更简单的方法:直接使用 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);
}
回到顶部