最近遇到一个需求,要在网页上预览 tif
格式的图片,一开始以为可以像普通 JPG、PNG
图片一样直接通过 img
标签进行预览,但实际上浏览器是不支持直接预览 tif
格式的图片,只能通过一些手段,将图片格式转化为常用的图片格式,经过一番探索,这里介绍两个可以插件库,一个是 tiff
,一个是 utif
,两者用起来比较简单。
1、tiff
- 下载依赖
npm i tiff
- 项目中导入
import { decode as Tiff } from "tiff";
- 具体使用步骤
async function getData() {
const buffer = await fetch("xxx.tif").then((res) => res.arrayBuffer());
// 将请求到的 buffer 数据进行解析,得到 tif 文件的宽高和一个 Uint8Array 数组
const { data, width, height } = Tiff(buffer)[0];
// 得到图片的宽高和 Uint8Array 数据,那么问题就简单了,我们只需要通过这些数据通过画布画出来
// 通过调用画布的 toDataURL 就可以将画布的数据转化为一个 base64 的图片链接
return canvasToImage({data, width, height})
}
const canvasToImage = (data: any) => {
const canvas = document.createElement("canvas");
canvas.width = data.width;
canvas.height = data.height;
const ctx = canvas.getContext("2d");
// 转化 imageData 数据的格式
const imageData = getImageData({ ...data });
ctx.putImageData(imageData, 0, 0);
const url = canvas.toDataURL("image/png");
return url;
};
const getImageData = ({ width, height, data: source }: any) => {
const imageData = new ImageData(width, height);
const data = imageData.data;
for (let i = 0; i < source.length; ++i) {
data[i] = source[i];
}
return imageData;
};
2、utfi
utif
这里我只用关键的代码,直接在 git 仓库下载下来核心 js 文件,在项目中导入,如果想要通过依赖库下载也是可以的;
- 下载依赖
npm i utif
- 项目中导入
// 这里是我自己的项目导入位置,我拿的是核心文件,足以
import "./util.js"
- 具体使用步骤
- 第一种:
decode
配合deccodeImage
使用,使用canvas
生成图片链接 - 第二种:直接使用
UTIF
工具的bufferToURI
转换,适合单张图的 tif 文件
- 第一种:
// 第一种实现方式
async function getData() {
const buffer = await fetch("xxx.tif").then((res) => res.arrayBuffer());
// 通过 UTIF 工具进行解码,这里因为在项目中导入了核心文件,它是挂在全局上的,所以可以直接用
// ifds 是一个数组,里面存的是每张图的数据,这里以一张图的 tif 为例
const ifds = UTIF.decode(buffer);
// 如果是多图的 tif 文件,可以循环遍历拿到每张图的链接
UTIF.decodeImage(buffer, ifds[0]);
return canvasToImage(idfs[0])
}
const canvasToImage = (ifd: any) => {
const { data, width, height } = ifd
const canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext("2d");
const rgba = UTIF.toRGBA8(ifd);
const imageData = new ImageData(new Unit8ClampedArray(rgba.buffer), width, height);
ctx.putImageData(imageData, 0, 0);
const url = canvas.toDataURL("image/png");
return url
};
// 第二种实现方式
async function transformTIF() {
const buffer = await fetch('xxx.tif').then(res => res.arrayBuffer());
// bufferToURI 内部实现也是通过 decode 和 decodeImage 进行转换,只是这里做了一层封装
const url = UTIF.bufferToURI(buffer);
console.log(url);
}