LibTiffCore 2.0.1
dotnet add package LibTiffCore --version 2.0.1
NuGet\Install-Package LibTiffCore -Version 2.0.1
<PackageReference Include="LibTiffCore" Version="2.0.1" />
<PackageVersion Include="LibTiffCore" Version="2.0.1" />
<PackageReference Include="LibTiffCore" />
paket add LibTiffCore --version 2.0.1
#r "nuget: LibTiffCore, 2.0.1"
#:package LibTiffCore@2.0.1
#addin nuget:?package=LibTiffCore&version=2.0.1
#tool nuget:?package=LibTiffCore&version=2.0.1
LibTiffCore — BigTIFF/SVS 数字病理图像读取库
高性能读取 BigTIFF/SVS 格式数字病理全片图像(Whole Slide Image),专为 GB 级超大图像设计,适用于数字病理阅片、远程病理、AI 分析与遥感影像等领域。针对 Web 高并发访问场景做了句柄池与缓存优化。
🔥 核心特性
- 金字塔瓦片索引:多分辨率层快速定位,按需读取 JPEG 瓦片,支持区域检索
- 稀疏层自动回退:间隔层(稀疏层)缺失瓦片自动从相邻完整层合成,调用方无感
- 文件句柄池:句柄复用 + 元数据缓存 + 空闲回收,高并发下不泄漏句柄
- 线程安全:
ReadTileImg等读取接口内部加锁,多线程共享同一代理不会串读 - JPEG 双后端解码:包内自带全平台 TurboJPEG native;缺库时自动降级 SkiaSharp,永不抛
DllNotFoundException - 统一接口:与 LibCspCore(CSP 格式)共享
IWSIInfo/IWSILayerInfo/IWSIReaderProxy/IWSIReaderPool,多格式集成零成本 - 异步 API:
GetReaderAsync等异步接口,避免 UI 线程阻塞 - 跨平台:Windows(x86/x64)、Linux(x64/arm64, glibc/musl)、macOS(x64/arm64)
⚠️ 仅支持 BigTIFF(不支持经典 TIFF 的 32 位偏移)。
📦 安装
dotnet add package LibTiffCore --version 2.0.0
🚀 快速开始
using LibTiffCore;
// 创建读取池(超时/清理间隔/缓存过期/最大句柄数)
var readerPool = new TiffReaderPool(
TimeSpan.FromSeconds(100), TimeSpan.FromSeconds(500),
TimeSpan.FromSeconds(120), 10);
// 异步获取读取代理(线程安全)
var reader = await readerPool.GetReaderAsync(@"F:\slides\case1.svs");
var info = reader.TiffImg;
Console.WriteLine($"格式: {info.SvsFormat}");
Console.WriteLine($"全图尺寸: {info.Width} x {info.Height}");
Console.WriteLine($"总层数: {info.Layers.Count}");
// 各层几何信息
for (short l = 0; l < info.Layers.Count; l++)
{
var ly = info.Layers[l];
Console.WriteLine($" L{l}: {ly.Width} x {ly.Height}, 瓦片: {ly.Cols} x {ly.Rows}, TileSize: {ly.TileWidth} x {ly.TileHeight}");
}
// 读取瓦片(JPEG 原始字节)
byte[] tileJpeg = reader.ReadTileImg(level, row, col);
// 读取嵌入文件 / 附加图像(标签图、缩略图等)
foreach (var kvp in info.IfdFiles)
{
byte[] bytes = reader.GetAssociatedImageJpegBytes(kvp.Value);
}
🌍 跨平台支持(2.0.0+)
| OS | 架构 | JPEG 解码 | 说明 |
|---|---|---|---|
| Windows | x86/x64 | TurboJPEG(自带) | 与 1.x 行为一致 |
| Linux glibc | x64/arm64 | TurboJPEG(自带) | 包内 runtimes/linux-*/native/libturbojpeg.so,FDD 发布自动跟随 |
| Linux musl(Alpine) | x64/arm64 | TurboJPEG(自带) | 包内 runtimes/linux-musl-*/native/,发布请用 -r linux-musl-x64 |
| macOS | x64/arm64 | TurboJPEG(自带) | 包内 runtimes/osx-*/native/libturbojpeg.dylib |
解码双后端:TurboJPEG 可用时走 Turbo(高性能),缺库时(PlatformSupport.TurboJpegAvailable == false)自动降级到 SkiaSharp 解码,ReadTileImg 照常返回有效 JPEG,只是稍慢。调用方永远看不到 DllNotFoundException。
Linux 宿主注意:SkiaSharp 主包只带 Win32/macOS native,Linux 需宿主显式引用同版本 SkiaSharp.NativeAssets.Linux(否则缺 libSkiaSharp.so):
dotnet add package SkiaSharp.NativeAssets.Linux --version 3.119.4
macOS/Windows 宿主无需额外引用。
自带系统级 libjpeg-turbo 时也可直接依赖系统库(需 LD_LIBRARY_PATH/macOS DYLD_LIBRARY_PATH 能找到 libturbojpeg.so(.0)/libturbojpeg.dylib),包内版本仅作兜底。跨平台实测记录:Turbo/Skia 双后端解码像素 MSE=1.688(阈值 3.0),统一入口输出恒为 Rgba8888。
📧 联系方式
如有问题,请发邮件至:kkkwp@foxmail.com
⚠️ 许可证
MIT 许可证(中文版附加非商用条款)。请勿用于商业用途,仅供学习交流使用。详见 LICENSE。
📜 更新日志
2.0.0(2026-09)跨平台版本
- 删除 PlatformTarget(库不锁平台,位数由宿主决定),RID 扩展 8 个
- 路径比较按平台分流(Windows 大小写不敏感,Linux/macOS 敏感)
- 新增
PlatformSupport探测与JpegCodec双后端,SkiaSharp 升级 3.119.4 稳定版 - 破坏性变更:x86 宿主需自行确认(库不再强制 x64)
1.3.9(2026-09-11)
[A] 修复排查稀疏层错位报告时发现的三个瓦片读取缺陷,均可能导致瓦片请求返回错误或损坏的图像数据:
线程安全(TiffReaderProxy / TiffReaderMutil)
ReadTileImg、ReadTileImgStream、ReadTileImgStream2、ReadBytes、GetFileSectionStream、ReadLayerByte在同一个共享 FileStream 上执行 Seek + Read 却没有加锁——尽管该类文档标注为"线程安全"读取器。并发调用同一代理实例时操作会交错:线程 A Seek 到偏移 X,线程 B Seek 到偏移 Y,随后线程 A 读到 B 的字节,调用方拿到的是别的瓦片的图像。表现为"瓦片之间对不上",随机、难以复现。现在所有 Seek + Read 位置都加了lock (_fs)。短读未检测(TiffReaderProxy.ReadTileImg / TiffReaderMutil.ReadLayerByte) 瓦片字节用单次
Read()读取且忽略返回值。FileStream.Read 允许返回少于请求量的字节,此时缓冲区尾部保持全零,JPEG 被截断补零,解码出损坏或半块瓦片。两处均已改为循环读取直至读满请求字节数,与既有的ReadTileImgStream实现一致。代理文件句柄泄漏(TiffReaderPool) GetReader / GetReaderAsync 每次调用都打开新的 FileStream 并注册进 _proxyStreams,但从未回收:CleanupOldHandles 只扫描 _fileHandles,而 _fileHandles 始终为空(GetOrCreateFileHandle 从未被调用),导致 fileHandleTimeout、cleanupInterval、maxHandles 全部失效。不 Dispose 的调用方(例如每个请求读一个瓦片的 Web API)每个请求泄漏一个句柄,直到 "new FileStream" 抛异常;异常被上游吞掉,客户端看到随机空白瓦片。现在新增 ProxyStreamInfo 记录最后访问时间,TiffReaderProxy 每次读瓦片时刷新,空闲代理流超过 fileHandleTimeout 后回收。
[B] 记录了所报告稀疏层错位的根因——这不是坐标映射问题。见下方 1.3.3:文件的 Tag 322/323 声明 256x256 瓦片而实际按 512x512 存储。已在 F:\ScanUpload4\2026-08-28\TP220519029(1).svs 验证:
Tag 322 TileWidth = 256, Tag 323 TileLength = 256
Tag 324 TileOffsets 条目数 = 30609
按 tag 值推算网格 : 357 x 341 = 121737 (不一致)
按条目数反推网格 : 179 x 171 = 30609 (一致, 真实尺寸 512)
L8(56,62) 确实有存储数据,对应 L7(28,31);象限矩阵、像素偏移搜索与 49 个真实存储瓦片的真值对照(中位 MSE 53.19)均确认映射正确。
注意:此修复仅在消费项目引用新包版本后生效。仅改源码不升版本——应用会继续运行旧程序集,直到版本更新、还原并重启宿主进程。
1.3.3(2026-09-11)
瓦片网格校验(InferTileSize):当 Cols * Rows 不等于 TileOffsets 条目数时,从条目数反推真实瓦片尺寸。某些 SVS 文件(如 TP220519029 的稀疏基层)在 Tag 322/323 写 256x256,而瓦片数据实际按 512x512 存储(条目数 = ceil(W/512) * ceil(H/512))。使用 tag 值会得到 357x341 网格而非正确的 179x171,导致 index = row * Cols + col 指向错误瓦片、稀疏层看起来与下层错位——这才是所报症状的真实根因。
1.3.2
修复特殊层(稀疏层)读取时自动从上一层拼接完整瓦片图的功能。
1.3.0
修复释放文件 bug。
1.2.8
实现统一通用接口继承(IWSIInfo/IWSIReaderProxy)。
1.2.6
支持生强 SVS,修复若干 bug。
1.2.3
修复 ReleaseFile 新 bug。
1.2.1(2026-05-21)
重大更新:支持标准 TIFF/SVS 格式数据解析。
1.2.0(2026-05-20)
支持其它 IFD 文件信息。
1.1.1(2025-10-27)
支持 .img 格式。
1.1.0(2025-10-22)
- 支持多文件合并 TIFF 格式解析
- 支持 IFD 层非图像文件数据与列表读取
- 支持流模式
1.0.5(2025-09-08)
新增强制释放所有文件句柄功能。
1.0.3(2025-09-01)
新增 WebP 支持。
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- libjpeg-turbo-net (>= 2.0.15)
- Microsoft.Extensions.Caching.Memory (>= 2.1.23)
- SkiaSharp (>= 3.119.4)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on LibTiffCore:
| Package | Downloads |
|---|---|
|
LibCspCore
CSP 数字病理全片图像(Whole Slide Image)跨平台快速读取库(.NET Standard 2.0)。 遵循中华医学会病理学分会《CSP 数字病理图像数据存储格式规范》,适用于病理阅片、远程病理与 AI 分析场景。 Cross-platform high-performance reader for CSP (Chinese Society of Pathology) digital pathology whole-slide images. 特性 Features: - Data Entry 树递归解析,支持 16/32/64 位寻址,完整提取金字塔层、瓦片索引、附加图像等元数据 - CSP 瓦片本身即 JPEG,ReadTileImg 直接返回原始字节,零转码开销 - 文件句柄池 + 元数据缓存 + SemaphoreSlim 并发控制,适配 Web 高并发阅片 - 私有信息(UID 0xFF000001)打包嵌入文件解析:Config.cfg、SlideInfo.json、AI 图块等批量嵌入文件 - 与 LibTiffCore(SVS/BigTIFF)共享 IWSIInfo/IWSILayerInfo/IWSIReaderProxy 统一接口,多格式集成零成本 - 依赖 LibTiffCore,跨平台能力与其一致:Windows(x86/x64)、Linux(x64/arm64, glibc/musl)、macOS(x64/arm64) |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.0.1 | 166 | 9/29/2026 |
| 1.3.4 | 93 | 9/10/2026 |
| 1.3.0 | 106 | 8/19/2026 |
| 1.2.9 | 110 | 7/9/2026 |
| 1.2.8 | 102 | 6/29/2026 |
| 1.2.7 | 97 | 6/29/2026 |
| 1.2.6 | 96 | 6/12/2026 |
| 1.2.5 | 89 | 6/11/2026 |
| 1.2.4 | 98 | 6/11/2026 |
| 1.2.3 | 107 | 5/28/2026 |
| 1.2.2 | 107 | 5/27/2026 |
| 1.2.1 | 94 | 5/21/2026 |
| 1.2.0 | 92 | 5/21/2026 |
| 1.1.5 | 84 | 5/20/2026 |
| 1.1.4 | 454 | 12/1/2025 |
| 1.1.3 | 199 | 10/31/2025 |
2.0.0 (2026-09) 跨平台版本:
- 库不再锁定 PlatformTarget(netstandard2.0,位数由宿主决定)
- RID 扩展至 8 个: win-x86/win-x64、linux-x64/linux-arm64、linux-musl-x64/linux-musl-arm64、osx-x64/osx-arm64
- JPEG 解码双后端: 包内自带全平台 TurboJPEG native,缺库时自动降级 SkiaSharp,不再抛 DllNotFoundException
- 文件路径比较按平台分流(Windows 大小写不敏感)
- SkiaSharp 升级至 3.119.4 稳定版
破坏性变更: x86 宿主需自行确认目标平台。