背景
由于我司多半项目是Gis遥感类的项目,难免要和.tif/.tiff文件打交道,有些业务场景就需要对它们做展示或预览。
相关概念
什么是tif文件?
.tif文件是一种高质量的、无损压缩的位图图像格式,适用于需要高精度图像处理的场景,如出版印刷、摄影测量与遥感等。
所需依赖
- tiff.js (npm i tiff.js)
demo效果
代码展示
template
用到了element-plus(^2.8.2)组件库
名称描述类型默认值on-change文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用Function-
<!-- template 部分 -->
<!-- 文件上传 部分 -->
<el-upload
ref="uploadRef"
class="UploadDemo"
:auto-upload="false"
:multiple="true"
:show-file-list="true"
:drag="true"
accept=".zip,"
v-model:file-list="uploadFileList"
:limit="2"
:on-remove="handleRemove"
:on-change="handleChange"
:on-exceed="handleExceed"
>
<template #trigger>
<el-icon size="30px"><upload-filled /></el-icon>
<div class="el-upload__text">拖拽文件或 <em>点击选择</em></div>
</template>
<el-button
style="margin-top: 10px"
type="success"
@click="submitUpload"
>
上传
</el-button>
<!-- v-loading.fullscreen.lock="fullscreenLoading" -->
<!-- <template #tip>
<div class="el-upload__tip">
大小小于等于500MB 的 tif/tiff 文件
</div>
</template> -->
</el-upload>
<!-- 图片展示 部分 -->
<el-image :src="src1" fit="cover">
<template #error>
<div class="image-slot">
<el-icon color="#ccc"><icon-picture /></el-icon>
</div>
</template>
</el-image>
script
Vue3 setup语法糖
注意点:必须要引入“Tiff”,并且在使用时要在“Tiff”的前面加上“window.”(window对象是bom的核心),否则也许会报“Tiff is not a constructor”的错误,如下面代码所示:
import Tiff from "tiff.js";
//缩略图url
let src1 = ref("");
// 上传文件
// 文件上传列表
let uploadFileList = ref([]);
// 文件改变事件
function handleChange(uploadFile, uploadFiles) {
console.log(uploadFile.raw, "改变");
uploadFileList.value.push(uploadFile.raw);
console.log(uploadFileList.value);
let fr = new FileReader();
fr.readAsArrayBuffer(uploadFile.raw); //要取文件的raw属性
fr.onload = function (e) {
window.Tiff.initialize({ TOTAL_MEMORY: 1024 * 1024 * 1024 });
let tiff = new window.Tiff({ buffer: e.target.result });
//
// 创建一个新的 Canvas 元素用于生成缩略图
let canvas = document.createElement("canvas");
let ctx = canvas.getContext("2d");
// 获取 TIFF 图像的宽度和高度
let width = tiff.width();
let height = tiff.height();
// 设定缩略图的尺寸,比如设置为原图的 1/20 大小
let thumbnailWidth = width / 20;
let thumbnailHeight = height / 20;
// 调整 Canvas 的大小为缩略图大小
canvas.width = thumbnailWidth;
canvas.height = thumbnailHeight;
// 绘制缩小后的图像到 Canvas 中
ctx.drawImage(tiff.toCanvas(), 0, 0, thumbnailWidth, thumbnailHeight);
// 将缩小后的图像转换为 Base64 URL
src1.value = canvas.toDataURL(); // 转换为 Base64 的缩略图
};
}
展示请求资源
上文中展示的代码是,在上传tif文件的时候,展示选择的本地tif图像,如果是展示请求的网络资源,可以参考下面这段代码:
template
<!-- 图片展示 部分 -->
<el-image :src="src2" fit="cover">
<template #error>
<div class="image-slot">
<el-icon color="#ccc"><icon-picture /></el-icon>
</div>
</template>
</el-image>
script
如果访问的网络地址被同源策略禁止的话,你可能需要使用代理来处理跨域问题
//script setup
import Tiff from "tiff.js";
let src2 = ref();
var xhr = new XMLHttpRequest();
xhr.responseType = "arraybuffer";
//"tifurl → 后端返回的tif文件http地址 例如:http://192.168.8.126:80/img/cs.tif"
xhr.open("GET", tifurl);
xhr.onload = function (e) {
window.Tiff.initialize({ TOTAL_MEMORY: 1024 * 1024 * 1024})
var tiff = new window.Tiff({ buffer: xhr.response });
// 创建一个新的 Canvas 元素用于生成缩略图
let canvas = document.createElement("canvas");
let ctx = canvas.getContext("2d");
// 获取 TIFF 图像的宽度和高度
let width = tiff.width();
let height = tiff.height();
// 设定缩略图的尺寸,比如设置为原图的 1/2 大小
let thumbnailWidth = width / 2;
let thumbnailHeight = height / 2;
// 调整 Canvas 的大小为缩略图大小
canvas.width = thumbnailWidth;
canvas.height = thumbnailHeight;
// 绘制缩小后的图像到 Canvas 中
ctx.drawImage(tiff.toCanvas(), 0, 0, thumbnailWidth, thumbnailHeight);
// 将缩小后的图像转换为 Base64 URL
src2.value = canvas.toDataURL(); // 转换为 Base64 的缩略图
// console.log("toDataURL:" + src2.value);
};
xhr.onerror = function (e) {
console.log("xhr onerror: ↓");
console.log(e);
};
xhr.send();
其他
处理超大文件的问题:
我在测试的时候,tif文件的大小在250MB左右,运行是没有问题的,如果不进行缩略图处理的话,页面会有明显卡顿。
也有尝试处理3GB左右的tiff文件,比如将“window.Tiff.initialize({ TOTAL_MEMORY: 1024 * 1024 * 1024 });”的值加大,或者在“fr.readAsArrayBuffer(uploadFile.raw);”这一步做截取,结果都失败了,如果大家有好的处理方法的话欢迎评论告诉我,不胜感激。
处理32-bit的tif文件问题:
tiff.js无法处理32位样本的图像,如下图所示:(24位测试是可以的)
版权归原作者 博客风气调查员 所有, 如有侵权,请联系我们删除。