likes
comments
collection
share

.tiff图片通过el-image显示出来.tiff图片在vue2框架中显示 最近项目中有个将tiff格式的图片需要显示

作者站长头像
站长
· 阅读数 17

.tiff图片在vue2框架中显示

最近项目中有个将tiff格式的图片需要显示+预览出来,格式如图

.tiff图片通过el-image显示出来.tiff图片在vue2框架中显示 最近项目中有个将tiff格式的图片需要显示

当拿到这个格式图片需要显示到页面上,当时看到脑袋发懵是第一次遇到平时也没有往这方面注意,当时如同晴天霹雳直击脑门,心想完蛋了,难道要被领导发现自己很菜了嘛,不行我要“垂死病中惊坐起”,最后在苦苦挣扎一下,于是乎开始疯狂的各种百度,各种搜,最后不负我这个有心人,终于被我百度出来了。

安装Tiff.js

npm install tiff.js yarn add tiff.js

引入依赖

import Tiff from 'tiff.js'

首先将tiff格式图片转化成base64格式,代码如下

// 异步获取图像数据 
const element = await getImg({ 
fileName: imgData.oriName, // 图像文件名,用于获取图像数据 
filePath: imgData.path, // 图像文件路径,用于获取图像数据 
}); 
// 等待图像数据加载完成,并将其转换为 ArrayBuffer 格式 
const arrayBuffer = await element.data.arrayBuffer(); 
// 使用 Tiff 库将 ArrayBuffer 转换为 TIFF 图像对象 
const tiff = new Tiff({ buffer: arrayBuffer, // 将 ArrayBuffer 作为缓冲区传递给 Tiff 对象 }); 
// 将 TIFF 图像对象转换为 PNG 格式的 Data URL 
let photoUrl = tiff.toDataURL("image/png");

存放在photoUrl字段中然后将el-image的src绑定photoUrl字段就显示出来

实现功能点击单张图片可以预览图片基本信息

点击轮播图上一个下一个来切换对应图片的数据信息

.tiff图片通过el-image显示出来.tiff图片在vue2框架中显示 最近项目中有个将tiff格式的图片需要显示

代码实现,首先通过父组件ref获取init方法来传参

<algorithmList-form
 v-if="detailEl"
 ref="algorithmListRef"
 :detailEl="detailEl"
></algorithmList-form>   
   
this.$refs.algorithmListRef.init(res.data.data.records, 0);

子组件代码如下

<template>
 <div>
   <el-dialog
     :title="formData.fileName"
     :visible.sync="visible"
     :close-on-click-modal="false"
     :append-to-body="true"
     :show-close="true"
     width="1000px"
   >
     <div>
       <div class="form-container">
         <div class="info-row">
           <div class="info-item">
             作物类型:
             <span class="info-label">{{ formData.cropType || "暂无" }}</span>
           </div>
           <div class="info-item">
             生长期:
             <span class="info-label">{{
               formData.growthPeriod || "暂无"
             }}</span>
           </div>
           <div class="info-item">
             拍照时间:
             <span class="info-label">{{
               formData.uploadTime || "暂无"
             }}</span>
           </div>
         </div>
         <div class="info-row">
           <div class="info-item">
             关联实验:
             <span class="info-label">{{
               formData.experimentName || "暂无"
             }}</span>
           </div>
           <div class="info-item">
             基地:
             <span class="info-label">{{ formData.houseName || "暂无" }}</span>
           </div>
           <div class="info-item">
             地块:
             <span class="info-label">{{ formData.areaName || "暂无" }}</span>
           </div>
           <div class="info-item">
             种植区:
             <span class="info-label">{{ formData.plotName || "暂无" }}</span>
           </div>
           <div class="info-item">
             相机编号:
             <!-- formData.experimentName ||  -->
             <span class="info-label">{{
               formData.cameraNumber || "暂无"
             }}</span>
           </div>
         </div>
       </div>
       <el-row :gutter="20">
         <el-col :span="detailEl ? 16 : 24">
           <div
             class="carousel"
             v-loading="loading"
             element-loading-text="拼命加载中"
             element-loading-spinner="el-icon-loading"
             element-loading-background="#fff"
           >
             <div
               class="carousel-inner"
               v-if="carouselItems && carouselItems.length > 0"
             >
               <div
                 class="carousel-item"
                 v-for="(item, index) in carouselItems"
                 :key="index"
               >
                 <el-image
                   class="dialog-image"
                   @click="getImages(item.img)"
                   :src="item.img"
                   v-if="item && item.img"
                   :preview-src-list="srcList"
                   fit="fill"
                 ></el-image>
                 <!-- <el-empty class="el-empty-box" v-else :image-size="200"></el-empty> -->
               </div>
             </div>

             <button
               class="carousel-control prev"
               @click="prevSlide()"
               v-show="carouselItems && carouselItems.length > 1"
             >

             </button>
             <button
               class="carousel-control next"
               @click="nextSlide()"
               v-show="carouselItems && carouselItems.length > 1"
             >

             </button>
           </div>
         </el-col>

         <el-col :span="8" v-if="detailEl">
           <div>
             <div
               class="info-label"
               style="font-size: 16px; padding-bottom: 10px"
             >
               计算结果
             </div>
             <div style="padding-bottom: 10px">
               穗粒数量&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;30颗
             </div>
             <div class="flex-container">
               <div class="flex-item" v-for="item in 14" :key="item">
                 {{ item }}号穗粒数量&nbsp;&nbsp;70
               </div>
             </div>
           </div>
         </el-col>
       </el-row>
     </div>
   </el-dialog>
 </div>
</template>

<script>
 import Tiff from "tiff.js";
 import { getImg } from "@/api/wheel-platform/acquisition";
 export default {
   name: "DialogForm",
   props: {
     detailEl: {
       type: Boolean,
       default: false,
     },
   },
   data() {
     return {
       visible: false,
       formData: {},
       dataList: [],
       carouselItems: [],
       currentSlide: 0,
       srcList: [],
       loading: false,
     };
   },
   components: {},
   mounted() {},
   methods: {
     init(value, index = 0) {
       this.carouselItems = [];
       this.currentSlide = index;
       this.visible = true;
       this.formData = {};
       this.formData = { ...value[index] };
       this.dataList = [...value];
       this.carouselItems = new Array(this.dataList.length).fill(null);
       this.loading = true;
       this.loadImage(this.currentSlide).then(() => {
         if (this.dataList.length > 1) this.loadImage(this.currentSlide + 1);
         if (this.dataList.length > 1) {
           this.currentSlide - 1 < 0
             ? (this.currentSlide = this.dataList.length - 1)
             : this.currentSlide - 1;
         }
         this.loadImage(
           this.currentSlide - 1 < 0
             ? this.dataList.length - 1
             : this.currentSlide - 1
         );
       });
       this.$nextTick(() => {
         this.showSlide(index);
       });
     },
     async loadImage(index = 0) {
       if (
         index >= 0 &&
         index < this.dataList.length &&
         !this.carouselItems[index]
       ) {
         const imgData = this.dataList[index];
         try {
           const element = await getImg({
             fileName: imgData.oriName,
             filePath: imgData.path,
           });
           const arrayBuffer = await element.data.arrayBuffer();
           const tiff = new Tiff({ buffer: arrayBuffer });
           let photoUrl = tiff.toDataURL("image/png");
           this.$set(this.carouselItems, index, {
             img: photoUrl,
           });
           this.loading = false;
         } catch (error) {
           console.error(`下标${index}数组获取失败`, error);
         }
       }
     },
     getImages(url) {
       this.srcList = [url];
     },
     showSlide(index) {
       const slides = document.querySelectorAll(".carousel-item");
       if (index >= slides.length) {
         this.currentSlide = 0;
       } else if (index < 0) {
         this.currentSlide = slides.length - 1;
       } else {
         this.currentSlide = index;
       }
       const offset = -this.currentSlide * 100;
       document.querySelector(
         ".carousel-inner"
       ).style.transform = `translateX(${offset}%)`;
     },
     nextSlide() {
       // 更新表单数据
       this.formData = {};
       this.formData =
         this.dataList[
           this.currentSlide + 1 > this.dataList.length - 1
             ? (this.currentSlide = 0)
             : (this.currentSlide = this.currentSlide + 1)
         ];

       if (
         this.currentSlide + 1 < this.dataList.length &&
         !this.carouselItems[this.currentSlide + 1]
       ) {
         this.loadImage(this.currentSlide + 1);
       }

       setTimeout(() => {
         this.showSlide(this.currentSlide);
       }, 100);
     },
     prevSlide() {
       this.formData = {};
       this.formData =
         this.dataList[
           this.currentSlide - 1 < 0
             ? (this.currentSlide = this.dataList.length - 1)
             : (this.currentSlide = this.currentSlide - 1)
         ];

       if (!this.carouselItems[this.currentSlide - 1]) {
         this.loadImage(this.currentSlide - 1);
       }

       setTimeout(() => {
         this.showSlide(this.currentSlide);
       }, 100);
     },
   },
 };
</script>

<style lang="less" scoped>
 .dialog-image {
   width: 100%;
   border-radius: 10px;
 }
 .carousel {
   position: relative;
   width: 100%;
   height: 500px;
   overflow: hidden;
   .carousel-inner {
     display: flex;
     transition: transform 0.5s ease;
   }

   .carousel-item {
     min-width: 100%;
     position: relative;
     .el-empty-box {
       // width: 100%;
       position: absolute;
       top: 100%;
       left: 50%;
       transform: translate(-50%, -50%);
     }
   }

   .carousel img {
     width: 100%;
     display: block;
   }

   .carousel-control {
     position: absolute;
     top: 50%;
     transform: translateY(-50%);
     background-color: rgba(240, 240, 240, 0.5);
     width: 40px;
     height: 40px;
     border-radius: 50%;
     color: #fff;
     font-weight: 900;
     font-size: 24px;
     border: none;
     // padding: 10px;
     cursor: pointer;
   }

   .carousel-control.prev {
     left: 10px;
   }

   .carousel-control.next {
     right: 10px;
   }
 }
 ::v-deep .el-dialog__body {
   padding-top: 10px;
 }
 .form-container {
   width: 760px;
   margin-bottom: 20px;
 }

 .info-row {
   display: flex;
   margin-bottom: 10px;
   flex-wrap: wrap;
 }

 .info-item {
   margin-right: 15px;
 }

 .info-label {
   color: #000;
   font-weight: 600;
 }
 .flex-container {
   display: flex;
   flex-wrap: wrap;
 }

 .flex-item {
   width: 50%;
   margin-bottom: 5px;
 }
</style>

存在问题tiff格式图片转成base64格式前端处理时间需要一到两秒,打开弹窗后也同样存在这个问题,如上代码中做了一点优化,比如当刚点击图片出现弹窗时就加载第一张图片,第一张图片加载完成后第二张和最后一张,当点击下一张时就加载第三张,点击最后一张时就加载倒数第二张,永远提前加载后一张或者前一张

转载自:https://juejin.cn/post/7398755501948682255
评论
请登录