如何使用名为 Tiff.js 的 LibTIFF javascript 库保存图像?
How can I save images using this LibTIFF javascript library called Tiff.js?
现在我使用 Tiff.js 库在 Node.js 中加载多图像 TIFF。 Tiff.js 库允许我使用 setDirectory 命令打开多图像 Tiff 和 select 图像。关于如何在服务器上保存每个图像有什么想法吗?
我的代码:
fs.readFile(path.resolve(__dirname, filename), function(err, data) {
if (err) {
throw err;
}
tiff = new Tiff({
buffer: data
});
console.log('width:', tiff.width());
console.log('height:', tiff.height());
console.log('currentDirectory:', tiff.currentDirectory());
console.log('countDirectory:', tiff.countDirectory());
for (var i = 0, len = tiff.countDirectory(); i < len; ++i) {
tiff.setDirectory(i);
}
tiff.close();
});
这实际上并不简单,因为 libtiff(tiff.js
所基于的)不直接支持此类操作。
我拼凑了一些代码,将每个目录写成 PNG 文件(使用 node-png
):
var path = require('path');
var fs = require('fs');
var Tiff = require('tiff');
var PNG = require('node-png').PNG;
fs.readFile(path.resolve(__dirname, filename), function(err, data) {
if (err) {
throw err;
}
var tiff = new Tiff({ buffer: data });
console.log('width:', tiff.width());
console.log('height:', tiff.height());
console.log('currentDirectory:', tiff.currentDirectory());
console.log('countDirectory:', tiff.countDirectory());
for (var i = 0, len = tiff.countDirectory(); i < len; ++i) {
writeLayer(tiff, i);
}
tiff.close();
});
function writeLayer(tiff, layer) {
tiff.setDirectory(layer);
var width = tiff.width();
var height = tiff.height();
var bufsiz = width * height * 4;
var raster = Tiff.Module.ccall('_TIFFmalloc', 'number', ['number'], [ bufsiz ]);
var result = Tiff.Module.ccall('TIFFReadRGBAImageOriented', 'number', [
'number',
'number',
'number',
'number',
'number',
'number'
], [
tiff._tiffPtr,
width,
height,
raster,
1,
0
]);
if (result === 0) {
throw new Tiff.Exception('The function TIFFReadRGBAImageOriented returns NULL');
}
var image = Tiff.Module.HEAPU8.subarray(raster, raster + bufsiz);
var png = new PNG({
filterType : -1,
width : width,
height : height
});
for (var y = 0; y < height; y++) {
for (var x = 0; x < width; x++) {
var idx = (y * width + x) * 4;
png.data[idx] = image[idx];
png.data[idx + 1] = image[idx + 1];
png.data[idx + 2] = image[idx + 2];
png.data[idx + 3] = image[idx + 3];
}
}
png.pack().pipe(fs.createWriteStream('layer-' + layer + '.png'));
Tiff.Module.ccall('free', 'number', ['number'], [raster]);
}
它没有经过优化,也没有经过很好的测试,但是我扔给它的 2 层 TIFF 被分成了两个单独的文件。
不知道直接用child_process.exec()
调用tiffsplit
(libtiff自带)是不是更麻烦
现在我使用 Tiff.js 库在 Node.js 中加载多图像 TIFF。 Tiff.js 库允许我使用 setDirectory 命令打开多图像 Tiff 和 select 图像。关于如何在服务器上保存每个图像有什么想法吗?
我的代码:
fs.readFile(path.resolve(__dirname, filename), function(err, data) {
if (err) {
throw err;
}
tiff = new Tiff({
buffer: data
});
console.log('width:', tiff.width());
console.log('height:', tiff.height());
console.log('currentDirectory:', tiff.currentDirectory());
console.log('countDirectory:', tiff.countDirectory());
for (var i = 0, len = tiff.countDirectory(); i < len; ++i) {
tiff.setDirectory(i);
}
tiff.close();
});
这实际上并不简单,因为 libtiff(tiff.js
所基于的)不直接支持此类操作。
我拼凑了一些代码,将每个目录写成 PNG 文件(使用 node-png
):
var path = require('path');
var fs = require('fs');
var Tiff = require('tiff');
var PNG = require('node-png').PNG;
fs.readFile(path.resolve(__dirname, filename), function(err, data) {
if (err) {
throw err;
}
var tiff = new Tiff({ buffer: data });
console.log('width:', tiff.width());
console.log('height:', tiff.height());
console.log('currentDirectory:', tiff.currentDirectory());
console.log('countDirectory:', tiff.countDirectory());
for (var i = 0, len = tiff.countDirectory(); i < len; ++i) {
writeLayer(tiff, i);
}
tiff.close();
});
function writeLayer(tiff, layer) {
tiff.setDirectory(layer);
var width = tiff.width();
var height = tiff.height();
var bufsiz = width * height * 4;
var raster = Tiff.Module.ccall('_TIFFmalloc', 'number', ['number'], [ bufsiz ]);
var result = Tiff.Module.ccall('TIFFReadRGBAImageOriented', 'number', [
'number',
'number',
'number',
'number',
'number',
'number'
], [
tiff._tiffPtr,
width,
height,
raster,
1,
0
]);
if (result === 0) {
throw new Tiff.Exception('The function TIFFReadRGBAImageOriented returns NULL');
}
var image = Tiff.Module.HEAPU8.subarray(raster, raster + bufsiz);
var png = new PNG({
filterType : -1,
width : width,
height : height
});
for (var y = 0; y < height; y++) {
for (var x = 0; x < width; x++) {
var idx = (y * width + x) * 4;
png.data[idx] = image[idx];
png.data[idx + 1] = image[idx + 1];
png.data[idx + 2] = image[idx + 2];
png.data[idx + 3] = image[idx + 3];
}
}
png.pack().pipe(fs.createWriteStream('layer-' + layer + '.png'));
Tiff.Module.ccall('free', 'number', ['number'], [raster]);
}
它没有经过优化,也没有经过很好的测试,但是我扔给它的 2 层 TIFF 被分成了两个单独的文件。
不知道直接用child_process.exec()
调用tiffsplit
(libtiff自带)是不是更麻烦