我们都知道openslide通过openslide_get_associated_image_names获取相关的图像名称,比如"thumbnail",“label”,“macro"等。那我们将"thumbnail”,“label”,"macro"写入tiff的时候,如何才能保证openslide能够获取到呢?
下面是openslide的部分源码:
do {
tdir_t dir = TIFFCurrentDirectory(tiff);
if (TIFFIsTiled(tiff)) {
...
} else {
// associated image
const char *name = (dir == 1) ? "thumbnail" : NULL;
if (!add_associated_image(osr, name, tc, tiff, err)) {
goto FAIL;
}
//g_debug("associated image: %d", dir);
}
} while (TIFFReadDirectory(tiff));
可以看到,openslide判断当前目录如果非tile块状结构,并且属于从下往上的第2层目录(dir == 1),则将该目录作为缩略图(“thumbnail”);并且通过add_associated_image添加该标签,添加后就能通过openslide_get_associated_image_names获取到了。
接下来再来看看add_associated_image的部分源码:
static bool add_associated_image(openslide_t *osr,
const char *name_if_available,
struct _openslide_tiffcache *tc,
TIFF *tiff,
GError **err) {
char *name = NULL;
if (name_if_available) {
name = g_strdup(name_if_available);
} else {
char *val;
// get name
if (!TIFFGetField(tiff, TIFFTAG_IMAGEDESCRIPTION, &val)) {
return true;
}
// parse ImageDescription, after newline up to first whitespace -> gives name
char **lines = g_strsplit_set(val, "\r\n", -1);
if (!lines) {
return true;
}
if (lines[0] && lines[1]) {
char *line = lines[1];
char **names = g_strsplit(line, " ", -1);
if (names && names[0]) {
name = g_strdup(names[0]);
}
g_strfreev(names);
}
g_strfreev(lines);
}
if (!name) {
return true;
}
bool result = _openslide_tiff_add_associated_image(osr, name, tc,
TIFFCurrentDirectory(tiff),
err);
g_free(name);
return result;
}
如果传入的name_if_available参数为NULL,则通过参数TIFFTAG_IMAGEDESCRIPTION获取当前目录的描述信息val,将val通过换行符\r和\n进行拆分得到字符串数组lines,如果lines个数大于1,则再将lines[1]通过空格进行拆分得到字符串数组names,如果names不为空则将names[0]作为标签写入tiff。
这下我们知道了,因此我们在往tiff文件中写入标签时,准确的添加该标签的描述信息就可以了,比如我要添加宏观图“macro”:
TIFFSetField(_tiff, TIFFTAG_IMAGEDESCRIPTION, "Aperio\rmacro");
下面是我写的转tiff的工具,支持"thumbnail",“label”,"macro"三种标签的写入。支持的格式包括江丰(kfb),麦克奥迪(mdsx),优纳(tmap),svs,vsi,lif等十几种格式。
工具下载地址:转TIFF工具下载链接