从System.Drawing.Image迁移至SkiaSharp处理TIF流文件的问题
SkiaSharp处理TIF流并生成PDF页面(替代System.Drawing.Image)
解决流被释放异常与Codec为null问题
出现System.ObjectDisposedException通常是因为原流在SkiaSharp处理过程中被意外关闭,或流不支持随机访问。解决方式是将原流复制到MemoryStream中,确保流始终处于可访问状态:
// 假设inputStream是你的TIF原流 using var memoryStream = new MemoryStream(); inputStream.CopyTo(memoryStream); memoryStream.Position = 0; // 重置流指针到开头 // 初始化SKCodec var codec = SKCodec.Create(memoryStream); if (codec == null) { throw new InvalidOperationException("无法创建TIF文件的SKCodec实例"); }
正确读取TIF的多帧内容
SKBitmap本身没有帧索引属性,需要通过SKCodecOptions指定FrameIndex来逐帧解码。完整逐帧处理逻辑如下:
var frameCount = codec.FrameCount; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { // 配置当前要解码的帧 var codecOptions = new SKCodecOptions { FrameIndex = frameIndex, TargetSize = SKSize.Empty // 保持原尺寸,按需修改 }; // 获取当前帧信息并创建对应尺寸的Bitmap var frameInfo = codec.GetFrameInfo(frameIndex); var bitmapInfo = new SKImageInfo(frameInfo.Width, frameInfo.Height, SKColorType.Rgba8888, SKAlphaType.Premul); using var bitmap = new SKBitmap(bitmapInfo); // 解码当前帧到Bitmap var result = codec.GetPixels(bitmapInfo, bitmap.GetPixels(), codecOptions); if (result != SKCodecResult.Success) { throw new InvalidOperationException($"解码第{frameIndex}帧失败,错误码:{result}"); } // 处理当前帧(如转换为XImage并添加到PDF) using var xImage = ConvertSkBitmapToXImage(bitmap); // 添加xImage到PDF页面的逻辑... }
SKBitmap转换为XImage的正确方式
将SKBitmap编码为临时PNG流(保留透明度),再通过XImage.FromStream加载:
private static XImage ConvertSkBitmapToXImage(SKBitmap bitmap) { using var imageStream = new MemoryStream(); // 将SKBitmap编码为PNG流 bitmap.Encode(imageStream, SKEncodedImageFormat.Png, 100); imageStream.Position = 0; // 转换为XImage(XImage会接管流,无需手动释放) return XImage.FromStream(() => imageStream); }
关键注意事项
- 所有SK系列对象(SKCodec、SKBitmap)必须用
using语句包裹,确保资源及时释放 - 若原流为不可重复读取类型(如网络流),必须先复制到MemoryStream再处理
- 解码时指定
SKColorType.Rgba8888和SKAlphaType.Premul可避免颜色格式兼容问题
内容的提问来源于stack exchange,提问作者usagibear
相关产品推荐
相关产品推荐

