.tiff图片通过el-image显示出来.tiff图片在vue2框架中显示 最近项目中有个将tiff格式的图片需要显示
.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字段就显示出来
实现功能点击单张图片可以预览图片基本信息
点击轮播图上一个下一个来切换对应图片的数据信息
代码实现,首先通过父组件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">
穗粒数量 30颗
</div>
<div class="flex-container">
<div class="flex-item" v-for="item in 14" :key="item">
{{ item }}号穗粒数量 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